2009-08-31 3 views
1

Рассмотрим таблицу с тремя столбцами: идентификатор (уникальный, взятый из последовательности 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 

?!

Что срабатывают триггеры и что происходит со вставкой?

ответ

7

Не используйте триггеры для такой проверки. Триггеры не масштабируются. Кроме того, как вы заметили, они не работают в многопользовательских средах. Вот почему Природа дала нам уникальные ограничения.

alter table your_table 
    add constraint yr_tab_uk unique (category, code) 
    using index 
/
+3

+1: используйте ограничения, а не триггеры, когда это возможно. В любом случае триггер не сможет запросить базовую таблицу, так как это приведет к ошибке MUTATION (ORA-4091). –

+0

@ APC эй, у меня есть аналогичный вопрос, подобный этому, только разница в том, что для определенной категории допускается только один Y, позволяя при этом множественное появление X, в этом случае 'unique' не подходит. –

+0

@JerryChin - звучит как совершенно другой сценарий, который вам нужен, чтобы задать новый вопрос. Обязательно включайте образцы данных, которые охватывают все состояния, которые у вас есть. – APC

Смежные вопросы