mysql事务隔离级别——序列化

  1. 借助mybatis来测试和理解mysql事务特性
  2. 一次session操作对应一次事务操作
  3. 序列化的意思就是本次事务序列化执行完毕之后,才允许其他事务的执行生效,如果这个期间其他事务也修改了相同的记录,那么以当前的事务修改为准。
  4. 为什么要序列化,因为会出现幻读错误
    幻读的意思是:我只查到五条数据,但是当我要插入第六条数据的时候,
    为什么又告诉我id重复,那说明我刚才读取到的五条数据是假的,魔幻的
    刚才读取的数据不足以支撑进行接下来的操作
  5. 复现幻读流程:
事务A事务B
开启事务,设置事务隔离级别为可以重复读取
查到五条记录
开启事务,插入一条记录id=6
事务提交
继续查询,依然查到五条记录
插入一条记录id=6
事务提交
报错id唯一性校验没有通过
  1. 设置事务隔离级别为序列化
事务A事务B
开启事务,设置事务隔离级别为序列化
查到五条记录
开启事务,插入一条记录id=6
事务提交 (并没有真正提交)
继续查询,依然查到五条记录
插入一条记录id=6
事务提交
事务回滚
报错id唯一性校验没有通过
  1. 相当于如果当前隔离级别为序列化,并且事务已经开启,没有其他事务的锁都释放了,那在你提交事务之前,所有操作都是你说了算,手握至高无上的权力,你就是宇宙的中心。

  2. talk is cheap,show me the code

    @Test
      void test() throws InterruptedException {
    
        try (SqlSession session = sqlSessionFactory.openSession(TransactionIsolationLevel.SERIALIZABLE)) {
    //    try (SqlSession session = sqlSessionFactory.openSession(TransactionIsolationLevel.REPEATABLE_READ)) {
          // 开启事务
          List<User> list = session.selectList("getAllUsers");
          assertEquals(5, list.size());
    
          // 开启子线程
          startThread();
    
          // 等待子线程插入数据
          Thread.sleep(1000);
    
          // 再次读取依然是刚才的数据,说明数据可以重复读取
          List<User> list2 = session.selectList("getAllUsers");
          assertEquals(5, list2.size());
    
          /**
           *
           * sqlSessionFactory.openSession(TransactionIsolationLevel.REPEATABLE_READ)
           * 出现幻读问题
           * 子线程插入数据成功
           * 主线程事务回滚
           *
           * sqlSessionFactory.openSession(TransactionIsolationLevel.SERIALIZABLE)
           * 解决幻读问题
           * 主线程插入数据成功
           * 子线程事务回滚
           *
           */
          insertUser(session, "user66666");
    
          User user = session.selectOne("getUsersById", 6);
          assertEquals("user66666", user.getName());
        }
    
      }
    
  3. 下载:github代码地址

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:书香水墨 设计师:CSDN官方博客 返回首页
评论

打赏作者

猿码YM

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值