Честность и конфиденциальность в распределенных транзакциях - PullRequest
0 голосов
/ 24 мая 2010

У меня вопрос по распределенным транзакциям. Предположим, у меня есть 3 программы транзакций:

Транзакция A

  1. начать
  2. а = READ (A)
  3. б = чтения (В)
  4. с = а + Ь
  5. запись (С, с) * * 1016
  6. 1018 * совершить *

Транзакция B

  1. начать
  2. а = READ (A) * * тысячу двадцать-восемь
  3. а = а + 1
  4. запись (А, а) * +1032 *
  5. 1034 * совершить *

Транзакция C

  1. 1042 * начать *
  2. с = чтения (С)

Итак, есть 5 пар критических операций: C2-A5, A2-B4, B4-C4, B2-C4, A2-C4.

Я должен обеспечить целостность и конфиденциальность , есть ли у вас идеи, как этого добиться?

Заранее спасибо!

1 Ответ

0 голосов
/ 24 мая 2010

То, что вы описали в своем посте, является распространенной ситуацией в многопользовательских системах.Различные сеансы одновременно запускают транзакции с использованием одних и тех же таблиц и одинаковых строк.Здесь есть две проблемы:

  1. Что происходит, если Сессия C читает запись после того, как Сессия A обновила ее, но до того, как Сессия A совершила свою торговую операцию ?
  2. Что произойдет, если сеанс C обновит ту же запись, которую обновил сеанс A, но не зафиксировано ?

(Ваш сценарий иллюстрирует только первую из этих проблем).

Ответ на первый вопрос - уровень ioslation.Это определение видимости незафиксированных транзакций между сеансами.Стандарт ANSI определяет четыре уровня :

  • SERIALIZABLE: никаких изменений из другого сеанса не видно.
  • REPEATABLE READ: фантомное чтение разрешено, то есть то же самоеВыполненный дважды запрос может вернуть разные результаты.
  • READ COMMITTED: видны только изменения, зафиксированные в другом сеансе.
  • READ UNCOMMITTED: diryt readsallowed, то есть незафиксированные изменения из одного сеанса видныв другом.

Различные разновидности или базы данных реализуют их по-разному, и не все базы данных поддерживают все из них.Например, Oracle поддерживает только READ COMMITTED и SERIALIZABLE, а также реализует SERIALIZABLE в качестве моментального снимка (т.е. это транзакция только для чтения).Однако для предотвращения неповторяющихся операций чтения в транзакциях READ COMMITTED используется многофакторный контроль параллелизма.

Итак, возвращаясь к вашему вопросу, вы получите ответ: установите соответствующий уровень изоляции.Какой соответствующий уровень зависит от того, какие уровни поддерживает ваша база данных и какое поведение вы хотите получить.Возможно, вы хотите READ COMMITTED или SERIALIZABLE, то есть вы хотите, чтобы ваши транзакции продолжались на основе значений данных, согласующихся с началом транзакции.

Что касается другого вопроса, ответ проще: транзакции должныПеред их обновлением создайте блокировки для таблиц или, желательно, только для нужных строк.Это гарантирует, что транзакция может продолжить изменять эти значения, не вызывая взаимоблокировку.Это называется пессимистической блокировкой.Это невозможно в приложениях, которые используют пул соединений (то есть в большинстве веб-приложений), и ситуация там гораздо сложнее.

...