您的位置:首页 > 编程语言 > Java开发

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的一级缓存不共享,每次查询都要读库,所以总是能读到被更新后的数据。(没有禁用一级缓存)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息