Spring中事务管理常见问题

1、Spring事务管理

Spring事务管理分为编码式声明式两种,编程式事务指的是通过编码方式实现事务,声明式事务基于AOP,将具体业务逻辑与事务处理解耦。
声明式事务有两种方式,一种是在配置文件(XML)中做相关的事务规则说明,另一种基于**@Transactional**注解的方式。

2、声明式事务(@Transactional)的使用:

1、xml配置事务:

<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

2、使用@Transactional注解

3、@Transactional常见问题

1、@Transactional 只能应用到 public 方法才有效

2、Spring的AOP自调用问题
在Spring的AOP代理下,只有目标方法由外部调用,目标方法才由Spring生成的代理对象来管理。
在同一个类中,一个没有@Transactional的方法调用有@Transactional注解的方法,则注解失效
原因:
Spring在扫描bean的时候,会扫描方法上面是否包含@Transactional注解,如果包含,则spring会为这个bean动态的生成一个子类(即代理类,proxy),代理类继承自原来那个bean。此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用之前就会启动transaction。 然而,如果该方法是由同一类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过调用方法的那个bean,就不会启动transaction,
导致@Transactional失效。
伪代码:


@Service
class A{
    @Transactinal
    method b(){...}
    
    method a(){    //标记1
        b();
    }
}
 
//Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个startTransaction()方法:
class proxy$A{
    A objectA = new A();
    method b(){    //标记2
        startTransaction();
        objectA.b();
    }
 
    method a(){    //标记3
        objectA.a();    //由于a()没有注解,所以不会启动transaction,而是直接调用A的实例的a()方法
    }

eg:https://blog.csdn.net/clementad/article/details/47339519

3.嵌套事务
嵌套事务有一个非常重要的特点是:内层事务依赖外层事务,外层事务失败时会回滚内存事务所做的操作,而内层事务失败则不会引起外层事务回滚。

@Transactional
methodA(){  
  doSomeThingA();  
  serviceB.methodB();  
  doSomeThingB();  
}  

@Transactional
methodB(){  
  ……  
} 

在调用methodA时,如果methodB调用失败,则撤回到doSomethingA()的保存点状态,如果methodB执行成功,但此时并没有提交,接着向下执行doSomeThingB()方法,如果doSomeThingB()方法执行失败,则回滚之前所有操作,包括methodB()中的操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值