面试-Spring事务

Spring事务分类

Spring中事务支持两种模式:编码式与声明式。
- 编码事务:硬编码实现事务,在需要事务的代码中手动开启事务,事务结束回滚或者提交。与JDBC开发类似
- 声明式事务:基于Spring AOP,通过切面完成事务管理。可以通过Xml定义切点、切面、通知等。也可以在需要事务的方法通过注解@Transactional完成。通过声明式事务,对代码低侵入

@Transactional位置

@Transactional注解可以添加到方法级别,也可以添加到类级别,当添加到类级别时,表示该类的公共方法都配置相同的事务属性。但是当方法也设置了@Transactional注解,应用程序会以方法的事务覆盖类级别事务。

事务的传播性(propagation)

  • REQUIRED:使用当前存在的事务,如果当前不存在事务,则新建事务
  • MANDATORY:仅使用当前事务,如果当前事务不存在,则抛出异常。一般用于子事务,数据没有独立存在的必要或者数据完整性考虑
  • NESTED:需要一个新事务,如果当前存在事务,则创建一个嵌套子事务,如果不存在,则直接创建事务。
  • REQUIRES_NEW:总是创建一个新事务,如果存在当前事务,则挂起当前事务,新建事务。
  • NEVER:就是强制要求不在事务中运行,如果当前存在一个事务,则抛出异常,因此如果bMethod传播性是NEVER,则一定抛出异常。
  • NOT_SUPPORTED的含义是,强制不在事务中运行,如果当前存在一个事务,则挂起该事务。
  • SUPPORTS的含义是,支持当前事务,如果没有事务那么就不在事务中运行。SUPPORTS传播性的逻辑含义比较模糊,因此一般是不推荐使用的。

NESTED与REQUIRES_NEW的区别

NESTED与REQUIRES_NEW是两个比较容易混淆的传播性,两者都是新创建一个事务进行处理,但是两者是有区别的。如有以下场景:存在两个方法,methodA与methodB,methodA处理业务过程中会调用methodB。
- 如果当前不存在事务,NESTED与REQUIRES_NEW是一样的,都是创建创建新的事务。methodA中无事务,调用methodB时,两种传播性都是新建一个事务。
- 如果当前存在事务,NESTED创建的新事务与当前事务相互依存,属于当前事务的子事务,而REQUIRES_NEW创建的事务与当前事务无关。
- 事务回滚机制不同。如果methodB抛异常,NESTED中,methodA与MethodB中事务都回滚。而REQUIRES_NEW则只回滚methodB中事务。如果methodB执行完毕,methodA执行失败,NESTED中,methodB与methodA中事务全部回滚,REQUIRES_NEW只回滚methodA

@Transactional 只能用到public修饰的方法

只有@Transactional 注解应用到 public 方法,才能进行事务管理。这是因为在使用 Spring AOP 代理时,Spring 在调用 TransactionInterceptor 在目标方法执行前后进行拦截之前,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource(Spring 通过这个类获取表 1. @Transactional 注解的事务属性配置属性信息)的 computeTransactionAttribute 方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值