【发布时间】:2011-01-31 01:38:29
【问题描述】:
我有一个网站,商店的所有分支机构都在使用它,它的作用是将客户购买记录到一个名为 myTransactions 的表中。myTransactions 表有一个名为 SerialNumber 的列。对于每次购买,我都会在交易表中创建一条记录并为其分配一个序列号。执行此操作的存储过程调用 UDF 函数以在插入记录之前获取新的序列号。如下所示:
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
该网站被不同商店的众多用户同时使用,并且创建了许多重复的序列号(相同的序列号)。所以我在事务中添加了一个 ReadCommitted 级别的 Sql 事务,我仍然得到重复的事务号。我将其更改为 SERIALIZABLE 以锁定资源,我不仅得到了重复的事务号(!!HOW !!),而且在相同的存储过程调用之间也出现了零星的死锁。这是我尝试过的:(省略了 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 函数调用中,但仍然得到重复的序列号。所以,存储过程行如何创建类似于 c# lock() {} 块的东西。 顺便说一句,我必须使用相同的模式来实现交易序列号,我不能将序列号更改为任何其他身份字段或其他任何东西。由于某些原因,我需要在数据库中生成序列号,但我不能将 SerialNumber 生成移至应用程序级别。
对不起,我已经在函数中没有 READUNCOMMITTED 的情况下尝试过这个,但我仍然得到重复的序列号。
至于 IDENTITY 列,我应该说这个应用程序将被其他需要不同 SerialNumber 的公司使用,我们不能简单地将其更改为身份。
【问题讨论】: