Mysql数据库隔离级别,spring事务传播,mybatis一级缓存
2017-03-04 18:07
363 查看
查询mysql当前的事务隔离级别
SELECT @@global.tx_isolation;###REPEATABLE-READ
在REQUIRES_NEW下,第一次读取后,更新数据库数据,前后两次结果
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=2}
在REQUIRES_NEW下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,会查询数据库,不会拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,更新数据库数据,前后两次结果(直接拿mybatis一级缓存)
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,不会查询数据库,会直接拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='mirofy', unumber=1}
开启事务时,如果没有禁用一级缓存,那么只要sql语句一样,每次都会从mybatis一级缓存获取数据;开启事务时,如果禁用了一级缓存,那么由于数据库隔离级别是可重复读,即使sql语句不一样,也不会查询最新的更改后的数据。
设置mysql隔离级别到READ COMMITTED
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@global.tx_isolation;###READ-COMMITTED
在REQUIRES_NEW下,第一次读取后,更新数据库数据,前后两次结果
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=2}
在REQUIRES_NEW下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,会查询数据库,不会拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,更新数据库数据,前后两次结果(直接拿mybatis一级缓存)
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,不会查询数据库,会直接拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='mirofy', unumber=1}
开启事务时,如果没有禁用一级缓存,那么只要sql语句一样,每次都会从mybatis一级缓存获取数据;开启事务时,如果禁用了一级缓存,那么由于数据库隔离级别是读提交,会查询最新的更改后的数据。
结论:
1. mybatis设置了一级缓存,在同一个事务中,读取完一次数据后,下次会从缓存中读取,不读数据库。此时,不论数据库隔离级别如何都不会产生影响。(没有禁用一级缓存)
2. 如果没有事务,那么每次读取,都会去获取一个sqlsession,而不同sqlsession的一级缓存不共享,每次查询都要读库,所以总是能读到被更新后的数据。(没有禁用一级缓存)
SELECT @@global.tx_isolation;###REPEATABLE-READ
在REQUIRES_NEW下,第一次读取后,更新数据库数据,前后两次结果
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=2}
在REQUIRES_NEW下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,会查询数据库,不会拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,更新数据库数据,前后两次结果(直接拿mybatis一级缓存)
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,不会查询数据库,会直接拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='mirofy', unumber=1}
开启事务时,如果没有禁用一级缓存,那么只要sql语句一样,每次都会从mybatis一级缓存获取数据;开启事务时,如果禁用了一级缓存,那么由于数据库隔离级别是可重复读,即使sql语句不一样,也不会查询最新的更改后的数据。
设置mysql隔离级别到READ COMMITTED
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@global.tx_isolation;###READ-COMMITTED
在REQUIRES_NEW下,第一次读取后,更新数据库数据,前后两次结果
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=2}
在REQUIRES_NEW下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,会查询数据库,不会拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,更新数据库数据,前后两次结果(直接拿mybatis一级缓存)
UserInfo{id=1, uname='kelvin', unumber=1}
更新后再读一次
UserInfo{id=1, uname='kelvin', unumber=1}
在REQUIRED下,第一次读取后,改变结果bean中的属性,比如执行:ui.setUname("mirofy"),再次读取时,不会查询数据库,会直接拿到被更新的值
UserInfo ui = userService.getUserById(1);// UserInfo{id=1, uname='kelvin', unumber=1}
System.out.println(ui.toString());
ui.setUname("mirofy");// 设置后,是否会清空一级缓存: 不会~
System.out.println(userService.getUserById(1).toString());// UserInfo{id=1, uname='mirofy', unumber=1}
开启事务时,如果没有禁用一级缓存,那么只要sql语句一样,每次都会从mybatis一级缓存获取数据;开启事务时,如果禁用了一级缓存,那么由于数据库隔离级别是读提交,会查询最新的更改后的数据。
结论:
1. mybatis设置了一级缓存,在同一个事务中,读取完一次数据后,下次会从缓存中读取,不读数据库。此时,不论数据库隔离级别如何都不会产生影响。(没有禁用一级缓存)
2. 如果没有事务,那么每次读取,都会去获取一个sqlsession,而不同sqlsession的一级缓存不共享,每次查询都要读库,所以总是能读到被更新后的数据。(没有禁用一级缓存)
相关文章推荐
- spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理
- Spring事务隔离级别与传播机制详解,spring+mybatis+atomikos实现分布式事务管理
- spring 事务传播属性解析
- Spring事务的传播行为和隔离级别
- 使用Spring注解方式管理事务与传播行为详解
- Spring事务传播特性总结
- spring里面事务的传播属性和事务隔离级别
- Spring中事务的传播属性详解
- Spring事务的传播行为
- spring事务传播特性
- Spring事务的传播行为和隔离级别
- Spring事务的传播行为和隔离级别
- spring 事务属性中的传播行为?
- Spring事务的传播行为和隔离级别
- Spring事务传播特性
- 5.spring中事务的传播属性
- Spring事务的传播行为和隔离级别
- Spring视频学习(九)使用Spring注解方式管理事务与传播行为详解
- 写给自己:关于Spring的事务传播属性
- [spring]事务传播级别隔离级别以及高并发下的应用经验