事务的隔离性

1、事务隔离级别

     事务有四大特性:原子性、一致性、隔离性、持久性。其中事务的隔离比较重要,事务隔离性处理在数据并发量较大的系统显得比较重要。

     数据库在事务隔离这块提供了四种事务隔离级别,分别是:读取未提交内容(Read Uncommitted),读取已提交内容(Read Committed),可重读(Repeatable Read),串行化(serializable)。

  不同的数据库关于事务隔离的默认级别不同,Oracle数据库默认的隔离级别为Read Committed, MySql的默认隔离之别则为Repeatable Read;

 

2、事务隔离级别对应产生的问题

     为什么不同的数据库采用了不同的默认隔离级别?因为不同的隔离级别在并发操作数据库时会产生不同的问题。 也就是由隔离级出现对应的问题:脏读、不可重复读及幻读

  先了解这几个问题的概念及产生。引用自:MySql事务隔离详解  

     (1) 脏读:在事务并发处理过程中,某一事务读取了另一个事务未提交的数据。如事务A读取到了事务B修改过的数据,但事务B未进行提交。

时间点事务A事务B
1select t.money  from t_account t where t.name='scl' 
2 update t_account t set t.money = t.money+1000 where t.name = 'scl'
3select t.money from t_account t where t.name = 'scl' 
4 commit

    假如 在两事务A、B 都未执行前,scl账号有1000元, 在事务开始后,如果事务A第一次读取到的数据为1000,第二次读到的数据为2000。那么这就出现了脏读。因为在两个不同事务里面应该是相互独立的。不应该读到其他事务的数据。

 

  (2)  不可重复读:在事务并发处理过程中,事务A在某时间点1内读到的数据跟时间点2读到的数据不一致。跟脏读的区别是,事务A先进行查询,然后事务B提交了某一行记录的修改,事务A再次查询数据发现两次读出来的数据不一致。(事务A读取了事务B提交的内容,两次查询某一行或几行数据内容不一致)

时间点事务A事务B
1select t.money  from t_account t where t.name='scl' 
2 update t_account t set t.money = t.money+1000 where t.name = 'scl'
3 commit;
4 select t.money from t_account t where t.name = 'scl' 

         假如 在两事务A、B 都未执行前,scl账号有1000元, 在事务开始后,如果事务A第一次读取到的数据为1000,第二次读到的数据为2000。那么这就出现了不可重复读。因为在      两个不同事务里面应该是相互独立的。A读到了B提交的事务,导致两次读取结果内容不一致。

    (3)  幻读:某事务A进行a表数据查询,然后事务B在a表内插入了一些新数据并且提交,事务A两次查询的数据条数存在差异。 与不可重复读得区别是数据条数增加了。

时间点事务A事务B
1select *  from t_account t   
2 

insert into t_account values ("1000","张三",2000);

insert into t_account values ("1000","李四",3000);

insert into t_account values ("1000","王五",4000);

insert into t_account values ("1000","钱六",6000);

3 commit;
4select *  from t_account t  

           假如 在两事务A、B 都未执行前,使用sql:select * from t_account 返回的是3条数据,在两事务开启后,事务A第一次读取到3条数据,在事务B提交后,事务A读取到了7条数据,那么久出现了幻读现象。

 

3、事务隔离级别应对事务并发产生的问题

  既然事务隔离级别不同会导致事务并发产生问题,那么四个事务隔离级别分别会产生什么问题?在开发时应选择什么哪个隔离级别方式?

隔离级别脏读不可重复读幻读

读取未提交内容(Read Uncommitted)

  √       √ √
读取已提交内容(Read Committed)  X       √ √
可重读(Repeatable Read)  X       X √
串行化(serializable)  X       X X

 

 

 

 

 

       

        可重读这个隔离级别有可能会出现幻读,有可能不出现。取决于数据库当时的实现。

4、事务隔离级别的查询与修改

   Mysql事务隔离有全局事务,会话事务之分。可以通过以下指令查询Mysql里面事务的隔离级别:

         1.SELECT @@global.tx_isolation; 

         2.SELECT @@session.tx_isolation;

         3.SELECT @@tx_isolation;

 
session 指的是当前连接的事务级别,global则是全局的隔离级别。应该使用gobal来设置全局事务隔离级别。并进行相关的测试。

修改事务隔离级别使用指令:set tx_isolation='read-committed';
或者完整的事务隔离更改方法: set global transaction isolation level READ COMMITTED;




需要注意的是:即使使用了全局事务隔离级别设置,但开启的窗口可能有session级别的缓存,把查询窗口关闭再进行一次查询即可确认事务级别是 否正确修改。(在64位Mysql5.5下测试过,无法在已开窗口下正确查询事务隔离级别)


以上为本人对Mysql事务隔离级别的学习总结,如有错误,烦请指出纠正。

      

 

转载于:https://www.cnblogs.com/doucheyard/p/5656610.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值