数据库并发问题

参考:http://blog.csdn.net/mageshuai/article/details/4544188

 1.丢失更新

时间 事务1 事务2
T1 开始事务  
T2   开启事务
T3 读取初始数据4  
T4   读取初始数据4
T5   4+10,并且更新到数据库
T6   提交事务
T7 4-4,并且更新到事务  
T8 报错  
T9 回滚事务  


这里T9回滚事务在一般情况下应该回滚到4,但是sqlserver未提交隔离级别(最低隔离)是回滚到事务2提交的结果:14,所以最终结果是14,也就是目前sqlserver不存在丢失更新的问题。

测试代码(最终结果:14):

--事务1
set transaction isolation level READ UNCOMMITTED
begin try
    begin tran
        declare @deptidTmp int
        WAITFOR DELAY '00:00:3'
        set @deptidTmp=(select deptid from Student where stuid=1) 
        WAITFOR DELAY '00:00:5'
        update Student set deptid=@deptidTmp-4 where stuid=1
        insert into department(depid,depname) values (1,'') --报错的语句
    commit tran
end try
begin catch
    rollback tran
end catch
--事务2
set transaction isolation level READ UNCOMMITTED
begin try
    begin tran
        declare @deptidTmp int
        WAITFOR DELAY '00:00:4'
        set @deptidTmp=(select deptid from Student where stuid=1) --读到4
        update Student set deptid=@deptidTmp+10 where stuid=1 --全部干掉,结果为0
    commit tran
end try
begin catch
    rollback tran
end catch

理论分析:事务1读完之后,对目标行没有加任何锁,事务2在读取和更新完成后,目标行数据变为14,事务1回滚到14而不是他一开始读的4,这可能是SQL SERVER的事务机制决定的。

              事务1读完之后,要想对目标行加上S锁,需要提升到可重复读隔离级别,这样事务2在更新的时候会被阻塞(等待),直到事务1回滚,才会把最终结果更新为14.

2.脏读

原文地址:https://www.cnblogs.com/wuMing-dj/p/5385719.html