方法一:@Transactional
- SpringBoot在使用事物Transactional的时候,要在main方法上加上 @EnableTransactionManagement 注解开发事物声明,在使用的service层的公共方法加上 @Transactional (spring)注解
@Transactional
public boolean test1(User user) throws Exception {
long id = user.getId();
System.out.println("查询的数据1:" + udao.findById(id));
udao.insert(user);
System.out.println("查询的数据2:" + udao.findById(id));
udao.insert(user);
return false;
}
方法二:手动回滚
- 如果我们在使用事物 @Transactional 的时候,想自己对异常进行处理的话,那么我们可以进行手动回滚事物。在catch中加上 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 方法进行手动回滚。不过需要注意的是发生异常需要第一时间进行手动回滚事物,也就是要在异常抛出之前!
@Transactional
public boolean test2(User user) {
long id = user.getId();
try {
System.out.println("查询的数据1:" + udao.findById(id));
udao.insert(user);
System.out.println("查询的数据2:" + udao.findById(id));
udao.insert(user);
} catch (Exception e) {
System.out.println("发生异常,进行手动回滚!");
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
e.printStackTrace();
}
return false;
}
方法三:子方法事务
- 如果我们在使用事物 @Transactional 的时候,调用了其他的子方法进行了数据库的操作,但是我们想使其事物生效的话,我们可以使用rollbackFor注解或者将该子方法的异常抛出由调用的方法进行处理,不过这里需要注意的是,子方法也必须是公共的方法!
@Transactional
public boolean test3(User user) {
try {
System.out.println("查询的数据1:" + udao.findById(user.getId()));
deal1(user);
deal2(user);
deal3(user);
} catch (Exception e) {
System.out.println("发生异常,进行手动回滚!");
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
e.printStackTrace();
}
return false;
}
public void deal1(User user) throws SQLException {
udao.insert(user);
System.out.println("查询的数据2:" + udao.findById(user.getId()));
}
public void deal2(User user) throws SQLException{
if(user.getAge()<20){
udao.insert(user);
}else{
user.setAge(21);
udao.update(user);
System.out.println("查询的数据3:" + udao.findById(user.getId()));
}
}
@Transactional(rollbackFor = SQLException.class)
public void deal3(User user) {
if(user.getAge()>20){
udao.insert(user);
}
}
方法四:编程事务
- 如果我们不想使用事物 @Transactional 注解,想自己进行事物控制(编程事物管理),控制某一段的代码事物生效,但是又不想自己去编写那么多的代码,那么可以使用springboot中的DataSourceTransactionManager和TransactionDefinition这两个类来结合使用,能够达到手动控制事物的提交回滚。不过在进行使用的时候,需要注意在回滚的时候,要确保开启了事物但是未提交,如果未开启或已提交的时候进行回滚是会在catch里面发生异常的!
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
@Autowired
private TransactionDefinition transactionDefinition;
public boolean test4(User user) {
TransactionStatus transactionStatus=null;
boolean isCommit = false;
try {
transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
System.out.println("查询的数据1:" + udao.findById(user.getId()));
udao.insert(user);
System.out.println("查询的数据2:" + udao.findById(user.getId()));
if(user.getAge()<20) {
user.setAge(user.getAge()+2);
udao.update(user);
System.out.println("查询的数据3:" + udao.findById(user.getId()));
}else {
throw new Exception("模拟一个异常!");
}
dataSourceTransactionManager.commit(transactionStatus);
isCommit= true;
System.out.println("手动提交事物成功!");
throw new Exception("模拟第二个异常!");
} catch (Exception e) {
if(!isCommit){
System.out.println("发生异常,进行手动回滚!");
dataSourceTransactionManager.rollback(transactionStatus);
}
e.printStackTrace();
}
return false;
}
方法五:断点回滚 (不推荐)
Object savePoint =null;
try{
savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
}catch(Exception e){
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
}
详细参考:https://www.cnblogs.com/xuwujing/p/11184162.html