本文学习参考:102-事务概述_哔哩哔哩_bilibili

本文仅用于加强学习记忆,如果需要系统学习就点击链接进行学习。

 

 

事务

  • 一个事务就是一个完整的业务逻辑,一个最小的工作单元,不可再分
  • 只有DML(insert、delete、update)语句和事务有关系其他都没关系。
    因为这三个语句是对数据库表中的数据进行增删改的。
    只要你的操作涉及到数据的增删改,那么就一定要考虑安全问题。

    数据安全第一位。
  • 最直白的说法就是,一个事务就是一批DML语句同时成功,或者同时失败
  • 事务的运行:
    InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
    eg:
    事务开启了:
    insert...
    isnert...
    delete...
    update...
    事务结束了。

    在事务执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。
    在事务执行过程中,我们可以提交事务,也可以回滚事务。
    提交事务:
      清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。
      提交事务标志着事务的结束,并且是一种全部成功的结束。
    回滚事务:
      将之前所有的DML操作全部撤销,并清空事务性活动的日志文件
      回滚事务标志着,事务的结束,并且是全部失败的结束。
  • 提交事务,回滚事务
    提交事务:commit;语句
    回滚事务:rollback;语句  (回滚只能回到上一次的提交点)

    事务对应的单词:transaction
    正常情况下,mysql是支持默认自动提交事务的。每执行一条DML语句就执行一次。
    如果需要关闭mysql自动提交事务,就使用start transaction;这个就是开启事务的指令。
    在使用了start transcation;后,如果一个事务结束就需要commmit指令或者rollback指令进行完成,否则你的事务是一直在记录,也就是说开启了start transcation指令,提交节点是你自己控制的,不再由mysql自动提交。
  • 事务包括四个特性:
    A:原子性
      说明事务是最小的工作单元,不可在拆分。
    C:一致性
      所有事务要求,在同一个事务中,所有操作必须同时成功,或者同时失败,以保证数据的一致性
    I:隔离性
      A事务和B事务具有一定的隔离。
      教室A和教室B之间有一道墙,这道墙就是隔离性。
      A事务在操作一张表的时候,另外一个事务B也在操作这张表会怎么样,也就是多线程并发的情况
    D:持久性
      事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘的数据保存到硬盘。





  • 事务的隔离性
    A教室和B教室中间有一道墙,这道墙可以很厚,也可以很薄。这就是事务的隔离级别。
    这道墙越厚,表示隔离级别越高

    事务和事务之间有4个隔离级别:
      读未提交: read uncommitted(隔离级别最低):
      事务A可以读取到事务B为提交的数据
        这种隔离级别存在的问题就是:
           藏读现象(Dirty Read):读到了脏数据


      读已提交:read committed:
      事务A只能读取到事务B提交后的数据
      这种隔离级别解决了脏读现象
      存在问题:不可重复读取数据。
        这种级别隔离是比较真实的数据,每一次读到的数据是绝对真实的。(oracle数据库默认的级别就是:read commited)



      可重复读:repeatable read:
        事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读。
      存在问题:会出现幻象读,每一次读取的数据都是幻象,不够真实。



      序列化,串行化:serializable(隔离级别最高):
      这种隔离级别最高,效率最低,解决了所有问题。
      这种隔离表示事务排队,不能并发。





  • 查看隔离级别:
    SELECT @@transaction_isolation;

     mysql默认隔离级别

  • 设置全局事务隔离级别:
    set global transaction isolation level read uncommitted;     将相应的隔离级别换掉就行。

     设置完后需要退出mysql重新加载级别,否则还是可重复级别


    使用t_user表测试隔离级别
    •   测试read uncommitted隔离:
      开两个终端进行事务验证,可以发现,两边都开手动提交,但是在事务未提交时,双方对数据的操作依然是实时更新的

      rollback再次查询:

       

  • 测试read committed隔离
    切换了隔离级别后,对右边终端开启start transaction;
    再对右端进行插入值操作,但是不提交,在左端进行查询,发现查不出来插入的信息,表依旧为空表。

     只有当我右端进行提交后,左端才能查出插入的表值。

     

  • repeatable read测试:
    将数据库隔离级别切换成repeatable read,打开两个终端进行测试,都开启事务,一个终端只管查询,另外一个终端进行表的插值最后进行提交,查询的表最终再查一次看看结果:
    发现进行插值的表就算提交了事务,另外一个终端也查询不到,

     只有在查询那张表事务进行提交后,再次查询才是显示最新的情况。

     



  • 验证序列化,串行化(serializable):
    先将数据库隔离级别设置为serializable
    再重启两个终端,开启事务,一个终端先对表进行插值,另外一个表再进行查询,结果如下:
    发现另外一个终端光标卡在那不动了,只有先插值的终端能进行操作,另外一个终端对相同的表进行操作给锁住了。