可以读出 人家没有提交的数据。这种情况会出现脏读,把人家没有提交的(修改数据的操作没有提交)数据给读出来了。
2、读已提交 read commited 可以设置,但是会出现不可重复读和幻读的情况。因为第一次读和第二次读,中间执行了增删改的操作且这个操作已经提交,导致第二次读出来的数据和第一次读出来的数据不一致,但是这个允许出现。因为毕竟读出来的是别人已经提交的数据。只能 读出人家已经提交的数据。
3、可重复读。repeated read就是确保这个事务在执行期间,不允许其他事务对我要读的数据进行更新。所以,我这个事务在每次读取的时候,都是一样的值。可以避免不可重复读的并发问题,在mysql数据库厂商还可以避免幻读并发问题。
4、串行话:(一万年不使用)整个数据库进入到单线程模式,性能十分低下。
总结: 回归到Spring事务的细节四: isolation Isolation数据类型,隔离级别
它提供这几种隔离级别。
测试:
我们发现结果是:
代理对象。
结论:
有事务的业务逻辑,容器中保存的是这个业务逻辑的代理对象。
事务的传播行为=
事务的传播 +
事务的行为。
如果有多个事务进行嵌套运行,那么子事务是否需要和大事务共用一个事务。
举例子:当C事务方法发生异常的时候,请问:B事务方法需要跟着进行回滚吗?
这两个使用的最多的,其他的基本不用。
举个例子:
两家人去旅游,
REQUIRED:如果朋友开车去,那我就不开车,做他的车子,翻车一起翻车。如果朋友不开车,那我只能自己开车了。
REQUIRES_NEW:不管朋友开不开车,我自己都开车去,它翻车和我无关。
1、 @Transactional(propagation = Propagation.REQUIRED) :举例子:
我们现在的BookService里面只有一个事务方法checkout()结账
现在再加一个:
1、首先 在Dao层定义一个修改图书价格的方法。
2、再在BookService类里面
所以现在在BookService里面有两个事务方法。
3、再写一个MulService。
这个类里面也有一个事务方法,且这个事务方法里面先后调用了BookService里面的两个事务方法。
这就是事务方法的嵌套。
现在的事务细节6 propagation就是来控制:
如果update方法出现了异常,问:
checkout方法需要回滚吗?
传播行为就是用来设置这个事务方法的。
第一种情况:
BookService里面的两个事务方法的事务行为全部设置成REQUIRED
这样就是说明,都需要事务,如果有,就和别人共用一个事务。
这个时候,如果执行updatePrice()的时候出现了异常,那么前面的checkout()也会回滚。
模拟updatePrice()方法出现异常
测试:
测试前,先恢复数据库的全部状态:
我们想要的预计结果就是:
谁都不变,因为updatePrice出错了,checkout方法也会回滚。数据库状态保持不变。
结果:都不变。
第二次测试:
我们的checkout的事务方法设置事务行为是REQUIRES_NEW
但是后面的updatePrice结账方法还是REQUIRED
测试:
预计的结果就是:
结账方法执行成功。(书本减库存和用户减余额都成功)
但是更新图书的价格失败。
结果也确实是这样。
始终记住:
REQUIRED是共用一辆车
而REQUIRES_NEW是开一辆新车。
两个子事务方法的事务行为全部为REQUIRED,那么这时候,大事务和两个小事务,这个时候全部都是共用一辆车子,只要一个完蛋,就全部完蛋。
异常在muxTx()方法的最后:且两个小事务方法的事务行为全为REQUIRES_NEW,那么这个时候相当于有三个事务。最后mulTx()发生异常。那么前两个事务方法都不会回滚。因为他们都各自是一个新事务,会自己进行提交。
回答问题:
B不回滚,整个D分支里面的全部方法都不回滚。
timeout=3是需要在这里去设置的。
在checkout()里面设置没用。
因为它和大事务是一辆车里面。
REQUIRED:是将之前事务用的connection传递给这个方法使用;
REQUIRES_NEW:这个方法直接使用新的connection
我们之前学习的是基于注解的声明式事务。 现在学一下,基于注解的声明式事务。之前:基于注解的声明式事务步骤:
现在:基于注解的声明式事务步骤:
我们先转走,过去学习javaweb的知识点。
学完javaWeb的知识点之后再来学Spring整合javaWeb的知识。
https://www.bilibili.com/video/BV1d4411g7tv?p=116&spm_id_from=pageDriver



