2010-02-05 28 views
1

我試圖刪除需要顯式鎖定下面的代碼的表,但從報告我一直得到它可能是該行中的參數和值遭受競爭條件。如果在單個更新語句中執行,SQL中的操作是否保證爲原子操作?

Declare @NextNumber Int; 

Update 
    MyParameterTable 
Set 
    NextNumber = NextNumber + 1, 
    @NextNumber = NextNumber + 1 

Select @NextNumber As NextNumber; 

希望你能看到它只是遞增一個整數並返回結果。我的印象是,以這種方式格式化的更新語句將處理必要的鎖定,但正如我所說的,可能是參數在更新鎖定之外被分配的情況。

任何人都可以拋出一些光,並建議一個替代?

問候

瑞安

回答

3

這將鎖定罰款,但你可以做一個三部分組成的平等聲明:

Declare @NextNumber Int; 

Update 
    MyParameterTable 
Set 
    @NextNumber = NextNumber = NextNumber + 1 

Select @NextNumber As NextNumber; 
+1

我不知道SQL讓你這樣做,謝謝。 –

+0

@Ryan ONeill:請注意,如果您在set語句中多次混淆@NextNumber,則此特殊語法可能會出現問題。 – ErikE

1

這是我的理解,那就是,你的查詢將沒有競爭條件或併發問題。

我也認爲@Variable = Column =/Expression /只是與最初發布的完全相同的查詢之上的語法糖。運行蹤跡並檢查獲得併發布的鎖定將證明這是明確的。

我不喜歡使用的語法,但是,因爲它可以有問題,有如下情況:

Update MyParameterTable 
Set 
    @NextNumber = NextNumber = NextNumber + 1, 
    @NextNumber = @NextNumber + 1 

雖然我知道你可能沒有想做到這一點,它打破了奇怪的方式(第一行處理與其他行不同)給了我相信它的意願。在SQL 2000的特定SP中,有一點也存在這種語法的錯誤。

如果您想要確保該行被正確鎖定,並且不會出現競態條件,那麼這是測試它的好方法。在SSMS/QA和每一個打開多個查詢窗口執行以下操作:

WAITFOR TIME '11:00:00' -- use a time in the near future 
EXEC dbo.YourProcedureName 

這會讓你在不同的會議上提交的,在本質上是完全一樣的瞬間運行批次,東西很難模仿任何其他方式。您很快就可以清楚地看到是否會出現競爭狀況。

我推薦一些文章給你做進一步閱讀的主題。他們不會因爲這個確切的問題,但肯定是相關的(對付在刀片比賽條件和更新):