Mysql数据库隔离级别,spring事务传播,mybatis一级缓存

3/8/2017来源:ASP.NET技巧人气:2014

查询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的一级缓存不共享,每次查询都要读库,所以总是能读到被更新后的数据。(没有禁用一级缓存)