事务隔离级别
http://blog.csdn.net/ocean1010/article/details/6548771
----------------------------------------------------------
0.丢失更新 (http://blog.csdn.net/mageshuai/article/details/4544188)
a.事务1撤销,把已经提交的事务2的更新给回滚掉了。(读写分开操作产生的不一致)
b.事务1覆盖掉了事务2更新的结果
1.脏读
一个事务读取另一个事务未提交的数据。
并发操作:写同时读。
2.不可重复读
一个事务两次按照相同的方式读的数据不一致。
并发操作:读同时写(update)。
3.幻读
一个事务两次按照相同的方式读的数据不一致。
并发操作:读同时写(add or delete)
总结:脏读是主动读在写的数据,是主动犯错;
不可重复读和幻读是读的时候数据被更改了;
丢失更新是在写的时候被其他事务的写冲突了。
----------------------------------------------------------
1.共享锁
允许同时读,不允许读的时候写。避免不可重复读。
2.独占锁
不允许同时读和写。解决不可重复读,丢失更新。
3.更新所
读阶段:允许同时读,不允许同时写。类似共享锁。
操作阶段:允许同时读,不允许同时写。类似共享锁。
更新阶段:不允许同时读,不允许同时写。类似独占锁。
4.意向锁
----------------------------------------------------------
1.读未提交(read uncommited)
没有锁。
2.读已提交(read committed)
当前事务的更新,会阻塞其他事务的读。
3.不可重复度(repeatable read)
当前事务的读,会阻塞其他事务的更新。
4.序列化(serializable)
当前事务的读(范围),会阻塞其他事务的更新和插入。
.NET中关于隔离级别的解释:
1.读未提交
允许其他事务在本事务期间读和修改。
2.读已提交
不允许其他事务在本事务期间读,允许修改。可以避免脏读。 Volatile data cannot be read during the transaction, but can be modified.
当前事务在写的时候,不允许其他事务同时读,也不可以修改。
当前事务在读的时候,允许其他事务同时读和写。
3.可重复读
不允许其他事务在本事务期间修改,允许插入。可以避免不可重复错误。
4.串行化
不允许其他事务在本事务期间插入。可以避免幻读。
----------------------------------------------------------
测试事务的sql语句
--READ UNCOMMITTED;READ COMMITTED;REPEATABLE READ;SERIALIZABLE set transaction isolation level REPEATABLE READ begin tran select * from coupon where couponid=245000 --select top 10 * from coupon where couponType='3' --update coupon set startdate='2014-10-07 00:00:00.000' where couponid='245546' WAITFOR DELAY '00:00:10' update coupon set startdate='2014-10-05 00:00:13' where couponid=245000 commit tran
--可以脏读,等于nolock
set transaction isolation level READ UNCOMMITTED
begin tran
select * from ActivityLog where ActivityLogid=2
commit tran
--不可以脏读
set transaction isolation level READ COMMITTED
begin tran
select * from ActivityLog where ActivityLogid=2
commit tran
--给select语句加上s锁,自己可以重复读
set transaction isolation level REPEATABLE READ
begin tran
select * from ActivityLog
WAITFOR DELAY '00:00:20'
commit tran
--给select语句加上range-s锁,不允许插入
set transaction isolation level SERIALIZABLE
begin tran
select count(1) from ActivityLog
WAITFOR DELAY '00:00:10'
commit tran
--查看系统锁资源
select * from sys.dm_tran_locks
----------------------------------------------------------
联想到java的读写锁,规则是:
写写互斥 (防止更新覆盖)
读读共享(数据的都是这样,起码保证可见性,程序里面的互斥锁就是都不可见,例如sychronized当一个线程锁定资源后,另一个线程就会被阻塞,直到锁释放)
读写互斥(在DB里面,读的时候不能写,可以防止不可重复读的问题, 写的时候不能读可以防止脏读的问题,幻读的问题是DB特有的,程序里面不存在这个问题)