问题如题,就是select * from ttt where id=1后,其他事务就不可以访问这一条数据,需要等待 本事务结束后,释放锁后,再访问,可以实现么? 我是要解决一个库存校验的问题,多人并发,检查库存,可能都满足数量要求,但保存后就可能有的已经超出库存了, 所以我想在校验库存时锁住行,让并发的其他事务等候,等当前事务结束后,其他并发再抢,可以实现么?
[Quote=引用 16 楼 flowingdream 的回复:]
begin tran
select * from tbl with(updlock) where id=1
update tbl set Content='1_1112' where ID=3
commit tran
发现 id=3的数据的Content内容一样被改了
[/Quote]
测试语句些错了,select和update在同一个事务中,是一个进程,当然是update能成功了。
应该是在SSMS中新建一个查询,输入begin tran
select * from tbl with(updlock) where id=1,注意不要commit或者rollback
然后在新开一个查询窗口,输入 update tbl set Content='1_1112' where ID=3,此时会发现update在等待。
这才是模拟两个并发的做法
所以我想在校验库存时锁住行,让并发的其他事务等候,等当前事务结束后,其他并发再抢,可以实现么?
[/Quote]
lz这种需求只是要求避免未提交读和幻影.可重复读是不影响你的设计的。只要保证事务依次进行就可以了,可以把隔离级别设成可串行化。 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
看看例子吧
conn1:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN ttt
update account set username='sdfdf' where userid=1;
waitfor delay '00:00:20'
commit tran ttt
conn2:
select * from account where userid=1;
需要等待conn1完成后conn2才能读取
conn1:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN ttt
select * from account where userid=1;
waitfor delay '00:00:20'
commit tran ttt
conn2:
update account set username='sdfdf' where userid=1;
需要等待conn1完成后conn2才能修改
conn1:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN ttt
select * from account where userid=1;
waitfor delay '00:00:20'
commit tran ttt
conn2:
insert into account(userid,username) values(2,'fafdsafasd')
需要等待conn1完成后conn2才能插入。