2013-04-25 5 views
1

У меня есть два запроса Oracle, которые работают в разных сеансах, которые являются взаимоблокирующими, и мне трудно понять, почему это происходит.Почему эти запросы блокируются?

Запрос в сессии 1 заключается в следующем:

UPDATE REFS R SET R.REFS_NAME = :B2 WHERE R.REFS_CODE = :B1 

Запрос в сессии 2 заключается в следующем:

UPDATE REFS R SET R.STATUS_CODE = :B3, R.STATUS_TYPE = :B2 WHERE R.REFS_CODE = :B1 

Каждый окружен курсором, что петли посредством выбора значений первичного ключа. Когда эти запросы запускаются одновременно, они блокируются. REFS_CODE является основным ключом, а трассировка Oracle показывает, что они обновляют разные rowid. Первичный ключ индексируется, очевидно, и есть некоторые ограничения внешнего ключа, которые поддерживаются индексами, поскольку это было проблемой для нас в прошлом.

Переходя в царство отчаяния, я попытался отключить триггеры на столе, и это не помогло. Также пытался использовать автономные транзакции, но это значительно ухудшало ситуацию.

Есть ли что-то, что мне не хватает? Спасибо за любую помощь!

+1

Только тангенциально: но почему вы используете курсоры вместо того, чтобы просто обновлять диапазон строк, которые вы хотите (возможно, используя что-то вроде второго ответа здесь: http://stackoverflow.com/questions/2446764/oracle-update-statement- с-внутрипартийной присоединиться)? – siride

+0

Какие транзакции у вас есть? – Marvo

+0

@Marvo не уверен, как ответить на это! Обычный вид? Они не являются AUTONOMOUS_TRANSACTION, если это то, что вы просите :) – Kieran

ответ

3

Если фиксация происходит после обновления всей партии курсора, это может быть просто прямой сценарий тупиковой ситуации, когда два курсора работают в одних и тех же строках, но в другом порядке.

  • Предположим session 1 имеет cursor set 1 и обновляет refs_code 1 и refs_code 2 в том порядке, прежде чем пытаться фиксации.
  • Предполагается, что session 2 имеет cursor set 2 и обновляет refs_code 2 и refs_code 1 в этом порядке перед попыткой совершить.

Затем перемежения обновления:

time cursor set 1 cursor set 2 
==== ============ ============ 

t1 refs_code 1  - 
t2 -    refs_code 2 
t3 refs_code 2  - 
t4 -    refs_code 1 

в t3, cursor set 1 ждет на cursor set 2 совершить refs_code 2 в t4, cursor set 2 ждет на cursor set 1 совершить refs_code 1

Обе сделки являются ожидая на разных рядах. Если это так, вы можете добавить order by (в том же направлении) для обоих курсоров, чтобы избежать этого.

+0

Спасибо, в этом была проблема! Ошибка вызвала сеанс 1 и сеанс 2 для обновления тех же записей. Теперь они - отдельные списки, тупик исчезает. – Kieran

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