【问题标题】:Spring @Transactional how to "stop" transactionSpring @Transactional 如何“停止”事务
【发布时间】:2015-07-19 05:15:46
【问题描述】:

我有一个控制器,它调用一个服务类的方法,它应该执行以下操作:

  1. 更新数据库(使用 DAO 1)
  2. 更新数据库(使用 DAO 2)
  3. sendEmail(使用电子邮件服务)

(1) 和 (2) 应该是原子的,如果两者都成功,则应该发送电子邮件。如果我用 @Transactional 注释服务方法,即使数据库更新失败(这是不希望的),也会发送电子邮件。此外,如果电子邮件失败,则数据库更新将回滚(这也是不希望的)。

我的理解是,将 3. 移至同一服务类上的单独方法无济于事。使用 @Transactional 和不同的传播行为(例如 NEVER 或 REQUIRES_NEW)注释 sendEmail 方法似乎也无济于事。

是否可以通过适当的注释来实现该行为?

【问题讨论】:

  • 你不能用 try/catch 包围你的 sendEmail 逻辑吗?

标签: java spring transactions transactional


【解决方案1】:

如果你想停止事务,则抛出新的RunTimeException("log message here"),并进行回滚。

【讨论】:

    【解决方案2】:

    您需要为前两个步骤创建一个事务,然后提交事务,最后发送电子邮件。最简单的方法是引入一个额外的 bean

    控制器:

    beanA.process();
    

    豆A:

    // not transactional
    public void process() {
        beanB.updateDatabase();
        sendEmail();
    }
    
    private void sendEmail() {
        ...
    }
    

    豆B:

    @Transactional
    public void updateDatabase() {
        dao1.update();
        dao2.update();
    }
    

    【讨论】:

    • 我这边的一些补充。请记住,可能需要 updateDatabase 方法必须位于与 process 方法不同的 bean 中。 (这取决于弹簧配置)。除此之外,您通常应该将电子邮件必须发送的数据库存储在数据库中。一些 cron/batch 作业检查会选择它并尝试发送它.....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2021-09-25
    • 2019-05-20
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多