Spring如何在⼀个事务中开启另⼀个事务
这篇⽂章主要介绍了Spring如何在⼀个事务中开启另⼀个事务,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下
spring使⽤@Transactional开启事务,⽽且该注解使⽤propagation属性来指定事务的传播级别
@Transactional(propagation =Propagation.REQUIRES_NEW) // 开启⼀个新事务
使⽤REQUIRES_NEW就会开启⼀个新的事务吗? 答案并不是.
请看下⾯的这个⽰例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ansaction.annotation.Propagation;
import ansaction.annotation.Transactional;
import qinfeng.zheng.learnpagequery.domain.UserDO;
import qinfeng.zheng.learnpagequery.mapper.UserMapper;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional(rollbackFor = Exception.class)
public void doSomething(UserDO userDo) {
insert(userDo);
doOther();
}
@Transactional(propagation =Propagation.REQUIRES_NEW) // 开启⼀个新事务
public void insert(UserDO userDo) {
userMapper.insert(userDo);
}
public void doOther() {
System.out.println("做⼀些其它的事,⽐如调⽤其它的系统");
}
}
在调⽤doSomething⽅法时,开启了⼀个事务,该⽅法中包括insert和doOther, 但是insert⽅法上也开启了⼀个事务. 按道理应该有两个事务控制,可事实上并不是, insert⽅法的事务⽆效. 这就跟spring事务原理有关系, spring框架是通过TransactionInterceptor 类来控制事务开启,提交,回滚等, 它会创建⼀个⽬标类的代理类. ⽽在本⽰例中,doSomething⽅法调⽤insert⽅法时,并不是通过代理类去调⽤,⽽是通过this调⽤本⾝的⽅法insert⽅法.所以insert⽅法的事务并不会开启.
解决⽅法
1. 将insert⽅法抽取到另⼀个XxxService⽅法中, 然后再将这个XxxService注⼊到UserService类中,通过xxxService.insert()调⽤, 这样insert⽅法的事务就会⽣效了.
2. 第2种⽅式通过AopContext创建⼀个代理
 在项⽬启动类上开启 exposeProxy = true
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
spring framework和spring的关系@Transactional(rollbackFor = Exception.class)
public void doSomething(UserDO userDo) {
UserService userService = (UserService) AopContext.currentProxy();
userService.insert(userDo); // 这样insert⽅法事务⽣效
doOther();
}
备注: 在springboot1.x中使⽤@EnableTransactionManagement开启事务, 但是在springboot2.x中,默认就开启了事务,所以勿须在启动类上添加此注解了
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。