3 回答

TA贡献1757条经验 获得超7个赞
只是为了清楚起见:
在其默认配置中,Spring 框架的事务基础结构代码仅在运行时、未经检查的异常情况下将事务标记为回滚。也就是说,当抛出的异常是 RuntimeException 的实例或子类时。(默认情况下,错误实例也会导致回滚)。从事务方法抛出的检查异常不会导致默认配置中的回滚。
请注意,您可以使用 的rollbackFor属性回滚业务异常@Transactional,例如:
@Transactionl(rollBackFor=MyBusinessException.class)
public boolean myTransactionalMethod(){
// stuff here
}
对于您想要的内容,只需在方法 updateDB 结束时返回 true :
@Transactional
public boolean updateDB(entity1, entity2, entity3, entity 4) {
save(entity1);
save(entity2);
save(entity3);
save(entity4);
return true;
}
如果它不返回 true,则意味着您的事务已回滚
PS:spring 文档中的另一个注释
在代理模式下(默认),只有通过代理传入的外部方法调用会被拦截。这意味着自调用(实际上,目标对象中的一个方法调用目标对象的另一个方法)在运行时不会导致实际的事务,即使调用的方法标记有@Transactional。此外,代理必须完全初始化以提供预期的行为,因此您不应在初始化代码(即@PostConstruct)中依赖此功能。

TA贡献1809条经验 获得超8个赞
您可以通过多种方式实现它,一种非常简单的方式实际上可能在最后返回 true 实际上只有当您的方法以返回指令结束时您才能获得结果并且事务管理器将向您保证事务已完成并且所有保存在同一笔交易中。
然而恳求!请注意,如果 save(entity) 方法属于 updateDB(....) 的同一类,即使您的类或方法标有 @Transaction,保存也不会在事务中。这是与 spring 自动代理相关的 Spring 的一个棘手的“功能”。神奇的 Transaction 被触发和传播,因为你的类被包裹到一个代理 Spring 为你管理事务的代理。这对于 Spring bean 来说是正确的,它在 bean 创建生命周期中被必要的组件代理。但是,如果在您的 @Transactional 类 A 中调用 A 类的其他方法,则您的服务调用不会从代理传递,并且第二个服务调用不在事务中。
我给你举个例子:
@Transactional
class A {
public Entity save(Entity e) {
.....
}
public Entity update(Entity e) {
.....
// the save method is not proxed becouse it is callled from the current instance and not
// form the proxed spring bean instance
save(e);
...
}
}
@Transactional
class SaveA {
public Entity save(Entity e) {
.....
}
}
@Transactional
class UpdateA {
private final SaveA saveA;
UpdateA(SaveA saveA) {
this.saveA = saveA;
}
public Entity update(Entity e) {
.....
// the save method is proxed becouse it is called from saveA that is a proxed bean
saveA.save(e);
...
}
}

TA贡献1900条经验 获得超5个赞
很难做到这一点。实际提交发生在 @Transactional 下的方法返回之后。例如,数据库需要做的一些检查是在数据写入表时完成的。例如,只有在数据写入磁盘时才会捕获数据库上的约束违规。到那时,该方法已经返回。因此,即使您从方法返回状态,您也会遇到当数据库由于某些错误执行回滚时您的方法返回成功的情况。
添加回答
举报