- 数据脏读复现
事务A | 事务B |
---|---|
开启事务,设置事务隔离级别为读未提交 | |
查到5条记录 | |
开启事务,插入一条记录id=6 ,事务并未提交 | |
继续查询,查到6条记录(脏数据) | |
事务回滚 | |
继续查询,查到5条记录 |
这样在事务A中就出现了脏读数据
- 事务脏读解决:
设置事务隔离为读已提交
事务A | 事务B |
---|---|
开启事务,设置事务隔离级别为读已提交 | |
查到5条记录 | |
开启事务,插入一条记录id=6 ,事务并未提交 | |
继续查询,依然查到5条记录(没有读到脏数据) | |
事务提交 | |
继续查询,依然查到6条记录 |
-
代码调试:
@Test void test() throws InterruptedException { try (SqlSession session = sqlSessionFactory.openSession(TransactionIsolationLevel.READ_COMMITTED)) { // try (SqlSession session = sqlSessionFactory.openSession(TransactionIsolationLevel.READ_UNCOMMITTED)) { // 开启事务 List<User> list = session.selectList("getAllUsers"); assertEquals(5, list.size()); // 开启子线程就相当于开启了一个事务 Thread thread1 = startThread(); // 等待子线程修改数据,但是并没有提交 Thread.sleep(1000); // 看本次是否读到脏数据 List<User> list2 = session.selectList("getAllUsers"); assertEquals(5, list2.size()); // 等待子线程执行结束 thread1.join(); // 暴露了不能重复读取问题 List<User> list3 = session.selectList("getAllUsers"); assertEquals(6, list3.size()); } }