在并发事务中加锁的示例代码

create table stock(material int,quantity int)--库存表
insert stock select 1,100 union all select 2,20
create table stock_out(id int identity,material int,quantity int)--出库单表
go
--出库表插入触发器,用于检查可用库存,并更新库存表减库存。
create trigger tr_stock_out_i on stock_out
for insert
as
begin
 set nocount on
 if exists(select 1 from inserted _i join stock _s with(updlock) on _s.material = _i.material
  where _i.quantity > _s.quantity
 )
 begin
  raiserror('库存不够!',16,1)
  rollback tran
  return 
 end
 else
 begin
  waitfor delay '00:00:05'--模拟并发事务
  update _s set _s.quantity = _s.quantity - _i.quantity
  from stock _s join inserted _i on _i.material = _s.material
 end
 
end
go
--如果不加锁,在两个连接中分别执行
waitfor time '15:12'
insert stock_out(material,quantity)
select 1,100
--然后
select * from stock where material = 1
--得
/*
material    quantity
----------- -----------
1           -100
库存出现负数,因为sql执行的顺序为
连接1检查库存,满足
连接2检查库存,满足
连接1减库存,减到0
连接2减库存,减到-100
检查库存与减库存这两个动作之间必须是无缝的,所以在检查库存时要加更新锁。
更新锁是自排斥的,并且与共享锁兼容,它会保持到事务结束即insert语句最外层的事务结束。
*/
go
drop table stock,stock_out
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值