2013-05-09 2 views
-1

Я ищу подходящий способ предотвращения возникновения проблем с блокировкой, вызванных несколькими процессами, пытающимися обновить одну и ту же запись в таблице. Я смог предотвратить блокировки, сначала выбрав запись WITH (UPDLOCK), затем выполнив обновление. Однако я не уверен, что это будет работать все время или если это вызовет другие проблемы с блокировкой, когда другие процессы вставляют новые записи или обновляют другие записи в этой таблице.Ошибка SQL Server Deadlocking

CREATE PROCEDURE usp_ReduceOrderAmount 
      @OrderId   INT, 
      @ReductionAmount INT 
AS 
BEGIN 

SET NOCOUNT ON 

DECLARE @dDateTime AS DATETIME     
SET @dDateTime = GETUTCDATE() 

BEGIN TRANSACTION 

--Quick Fix... Attempt to block other callers who are trying to update the same record. 
SELECT * FROM ORDERS WITH (UPDLOCK) WHERE ORDER_ID = @OrderId 

UPDATE dbo.ORDERS 
SET QTY_OPEN = QTY_OPEN - @ReductionAmount, 
UPDATED_WHEN = @dDateTime 
WHERE ORDER_ID = @OrderId   

COMMIT 

END 
+0

В тупике обычно задействовано как минимум 2 ресурса (таблицы). У вас есть сообщение об ошибке/сценарий? – davmos

+0

Почему у вас есть выбор в транзакции? почему у вас нет его за пределами транзакции? –

+0

вы также можете добавить с помощью (updlock) команду update – Jimbo

ответ

0

Во-первых, я не понимаю, почему у вас есть запрос на выбор внутри трансмиссии. Вы не используете его в запросе на обновление, поэтому я думаю, что вы можете вывести его на улицу.

Тогда, может быть, вы могли бы попытаться change your Isolation Level

SET TRANSACTION ISOLATION LEVEL 
    { READ UNCOMMITTED 
    | READ COMMITTED 
    | REPEATABLE READ 
    | SNAPSHOT 
    | SERIALIZABLE 
    } 
[ ; ] 

Может попробовать один из этого

READ UNCOMMITTED Указывает, что высказывания могут прочитать строки, которые были изменены другими транзакциями, но еще не совершали ,

REPEATABLE READ Указывает, что заявления не может читать данные, которые были изменены, но еще не совершенные другими транзакциями, и что никакие другие транзакции не могут изменять данные, которые были считаны текущей транзакции, пока текущая транзакция не будет завершена.

SNAPSHOT Указывает, что данные, считанные любым оператором в транзакции , будут последовательной версией данных, которые существовали в начале транзакции. Сделка может только распознать изменения данных, которые были совершены до начала транзакции. Изменения данных, сделанные другими транзакциями после , начинают текущую транзакцию, не отображаются в операциях , выполняемых в текущей транзакции. Эффект выглядит так, как если бы операторы в транзакции получали моментальный снимок данных, которые были установлены в начале транзакции, поскольку он .

SERIALIZABLE Указывает следующее: Заявления не могут читать данные, которые был изменен, но еще не совершены другими транзакциями. Нет другие транзакции могут изменять данные, которые были прочитаны текущей транзакцией , до завершения текущей транзакции. Другие транзакции не могут вставлять новые строки с значениями ключа, которые упадут в диапазон ключей, считываемых любыми операторами в текущей транзакции до завершения текущей транзакции.