为了账号安全,请及时绑定邮箱和手机立即绑定

spring boot @transactional 如果成功则为 true

spring boot @transactional 如果成功则为 true

蛊毒传说 2022-05-21 17:21:01
我正在使用带有 spring boot 的 spring 4,我需要使用 @transactional。如果我错了,请纠正我 - @transactional 使我的函数在与 db 的 1 个事务中运行,因此如果出现问题,该函数将执行回滚并且数据库中不会发生任何变化,否则它将提交。我需要同时更新 4 行(来自 4 个不同的表),如果其中一个无法更新,我需要回滚。所以在我的服务中,我有这个功能:@Transactionalpublic void updateDB(entity1, entity2, entity3, entity 4) {    save(entity1);    save(entity2);    save(entity3);    save(entity4);}现在我希望如果事务以提交结束,我的函数将返回 true,否则我希望它返回 false。有什么办法吗?
查看完整描述

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)中依赖此功能。


查看完整回答
反对 回复 2022-05-21
?
海绵宝宝撒

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);

        ...

    }


}


查看完整回答
反对 回复 2022-05-21
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

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



查看完整回答
反对 回复 2022-05-21
  • 3 回答
  • 0 关注
  • 245 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号