• 事务的隔离性


    1、事务隔离级别

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

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

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

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

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

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

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

    时间点 事务A 事务B
    1 select 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 select 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
    1 select 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
    1 select *  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;
    4 select *  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事务隔离级别的学习总结,如有错误,烦请指出纠正。

          

     
  • 相关阅读:
    error: declaration of 'cv::Mat R ' shadows a parameter
    Java网络编程(二)
    排序算法(二)
    Java网络编程(一)
    排序算法(一)
    Python文件访问模式
    Python文件与异常
    递归
    SQL命令的六个主要类别
    iOS-生成Bundle包-引入bundle-使用bundle
  • 原文地址:https://www.cnblogs.com/doucheyard/p/5656610.html
Copyright © 2020-2023  润新知