锁如何在insert ... select语句中工作?
两场会议中的两笔交易的运营项目与以下项目相同:
在会议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
如果就这样,两个相同的行将被插入表Orders中。 但我希望在任一会话中的事务先完成,然后另一个事务可以读取新的最大值(OrderNumber),然后插入下一个值。 我将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语句然后分配独占锁来插入语句? 在两个会话中,锁具是如何相互作用的? 感谢任何提示
您可以使用可序列化的隔离级别来处理事务。
例如:
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
可串行化选项将提供以下事务功能:
以上将适用于您的问题,但我会建议使用身份列而不是最大order_number + 1逻辑。 因此,将OrderNumber更改为表中的标识,并且当您读取数据时,请使用row_number编号按运算符中的Item计算订单编号,以下是一个示例查询:
select Item, Row_Number() over(partition by Item order by OrderNumber) as OrderNumber
from Invoice
所以上面的查询会给出你需要的结果。
你的最终目标是什么? 我不认为你不能在选择时停止带锁的插入,它只会锁定任何更新中的选定行。
数据库锁定方案是任何数据库管理应用程序的组成部分 为了存储在数据库中的数据的完整性,不同的数据库供应商提供不同的锁定方案。 您应该检查以下链接First Link
第二链接。 如果这些没有帮助,请让我知道,以便我可以进一步帮助您。
链接地址: http://www.djcxy.com/p/5615.html