我有一個網站,供商店的所有分支機構使用,它所做的是將客戶購買記錄到名爲myTransactions.myTransactions表的一個名爲SerialNumber的表中。對於每筆購買,我在交易表中創建一個記錄併爲其分配一個序列。執行此操作的存儲過程在插入記錄之前調用UDF函數以獲取新的serialNumber。如下圖所示:可序列化的事務隔離級別不適用於我
Create Procedure mytransaction_Insert
as begin
insert into myTransactions(column1,column2,column3,...SerialNumber)
values(Value1 ,Value2,Value3,...., getTransactionNSerialNumber())
end
Create function getTransactionNSerialNumber
as
begin
RETURN isnull(SELECT TOP (1) SerialNumber FROM myTransactions READUNCOMMITTED
ORDER BY SerialNumber DESC),0) + 1
end
該網站在同一時間被使用在不同的店這麼多的用戶,它是創造了許多重複的serialNumbers(相同SerialNumbers)。所以我在事務中添加了一個具有ReadCommitted級別的Sql事務,並且我仍然有重複的事務編號。我將其更改爲SERIALIZABLE以鎖定資源,並且我不僅獲得了重複的事務數(!!如何!!),而且在相同的存儲過程調用之間也有零星的死鎖。這是我的嘗試:(使用try catch塊的遺漏和回滾)
Create Procedure mytransaction_Insert
as begin
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRASNACTION ins
insert into myTransactions(column1,column2,column3,...SerialNumber)
values(Value1 ,Value2 , Value3, ...., getTransactionNSerialNumber())
COMMIT TRANSACTION ins
SET TRANSACTION ISOLATION READCOMMITTED
end
我甚至複製的直接獲取序列號到存儲過程,而不是UDF函數調用的函數,還是把重複serialNumbers。那麼,一個存儲過程如何創建一些類似於c#lock(){}的塊。 順便說一下,我必須使用相同的模式來實現事務序列號,並且我不能將serialNumber更改爲任何其他身份字段或任何內容。出於某些原因,我需要在數據庫中生成serialNumber,將SerialNumber生成轉移到應用程序級別。
對不起,但我已經嘗試過,沒有READUNCOMMITTED函數,我仍然得到重複SerialNumbers。
至於IDENTITY專欄,我應該說這個應用程序將被其他需要不同SerialNumbers的公司使用,我們不能簡單地將其改爲身份。
感謝您的sp_getapplock引用。我不知道這樣的事情存在! – zvolkov 2011-02-28 15:49:01