我有一个网站,供商店的所有分支机构使用,它所做的是将客户购买记录到名为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