Рассмотрим таблицу с 3 столбцами: ID (уникальный, взятый из последовательности Oracle), CATEGORY и CODE (без ограничений для этих двух последних).
К каждой категории прикреплено несколько кодов, но коды должны быть уникальными в этой категории. Пример:
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //wrong
Третий не в порядке, так как у нас уже есть код Y для категории 1.
Теперь рассмотрим триггер, который запускается перед вставками и проверяет, в порядке ли значения для вставки. То есть для вставляемой записи триггер читает категорию, а затем считывает все коды из таблицы, которая имеет эту категорию, и если код из записи, которая должна быть вставлена, уже существует, то возникает исключение, так что запись не вставлено.
У меня вопрос: что триггер «увидит» в таблице, если уровень изоляции транзакции равен READ_COMMITED
и две вставки выполняются в двух разных транзакциях практически в одно и то же время, но транзакция фиксируется позже?
Пример:
(1) Изначально таблица выглядит так:
ID CATEGORY CODE
1 1 X
(2) есть две транзакции T1 и T2 (уровень изоляции READ_COMMITED
для обеих);
(3) обе транзакции хотят вставить категорию = 1 и код = Y;
(4) T1 выполняет вставку и запускается триггер. В таблице нет буквы Y, поэтому ее можно вставлять;
(5) T2 выполняет вставку и запускается триггер. В таблице нет Y (T1 еще не зафиксировал), поэтому его можно вставлять;
(6) T1 фиксирует, и таблица теперь выглядит так:
ID CATEGORY CODE
1 1 X
2 1 Y
(7) T2 теперь фиксирует. Что здесь происходит? Я получаю сообщение об ошибке, и запись не вставляется, или я получаю следующую таблицу:
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //this is wrong
?!
Что триггеры "видят" и что происходит со вставкой?