两个会话中的两个交易在同一项目上运作:
在第1节:
begin tran T1
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders
where item='ItemA'
waitfor delay '00:00:05'
commit T1
在第2节:
begin tran T2
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders
where item='ItemA'
commit T2
如果是这样的话,两个相同的行将插入表中的订单。但我希望先在任一会话中执行事务,然后另一个事务可以读取新的max(OrderNumber)然后插入下一个值。我将holdlock添加到T1:
begin tran T1
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders with (holdlock)
where item='ItemA'
waitfor delay '00:00:05'
commit T1
SQl SERVER是否首先分配共享锁,因为它首先解析select语句然后为insert语句分配独占锁?在两个会话中,确切的锁如何相互作用?感谢任何提示
答案 0 :(得分:1)
您可以为事务使用可序列化隔离级别。
例如:
set transaction isolation level serializable
begin tran
insert into Invoice with (item,OrderNumber)
select 'ItemA', max(OrderNumber)+1
from Orders
where item='ItemA'
waitfor delay '00:00:05'
commit tran
Serializable选项将提供以下交易功能:
以上将适用于您的问题,但我建议使用标识列而不是max ordernumber + 1逻辑。因此,将OrderNumber更改为表中的标识,当您读取数据时,使用row_number编号按运行时按项计算订单编号,这是一个示例查询:
select Item, Row_Number() over(partition by Item order by OrderNumber) as OrderNumber
from Invoice
因此上述查询将提供您需要的结果。
答案 1 :(得分:0)
你的最终目标是什么?我不认为你不能阻止选择锁定的插入,它只会锁定任何更新中的选定行。
答案 2 :(得分:0)
数据库锁定方案是任何数据库管理应用程序的组成部分。对于存储在数据库中的数据的完整性,不同的数据库供应商提供不同的锁定方案。 您应该查看以下链接First Link
Second Link。如果这些没有帮助那么请告诉我,以便我可以进一步帮助你。