【问题标题】:Executing code before and after @Transactional method在@Transactional方法之前和之后执行代码
【发布时间】:2011-07-12 13:01:06
【问题描述】:

我们有一个基于 Spring 的应用程序,该应用程序带有一个使用 @Transactional 注释的服务层。我们需要在一些事务方法之前和之后运行代码,原因如下:

  1. 我们需要根据一个键来同步对方法的访问。线程需要在事务开始之前阻塞。
  2. 如果事务成功,我们需要在队列中发布消息。

选项似乎是:

  1. 使用与服务类似的方法创建一个类,该类可以在同步块中运行 @Transactional 方法并检查返回然后发布消息(由于 AOP 代理问题,需要单独的类)。服务调用服务,不是很好,感觉像是一种变通方法。
  2. 编写一个切面来包裹@Transactional AOP,它可以进行同步和消息发布。可能有效,但宁愿避免 AOP。
  3. 将事务向下移动到域层。由于在不同工作流中重用领域方法的方式,当前实现不理想甚至可能不可行。
  4. 在服务方法中手动编码事务并废弃@Transactional。

我想这是一个相当普遍的要求。可能我错过了选项 5,这是显而易见的!

【问题讨论】:

    标签: java spring


    【解决方案1】:

    我想我会选择 2,除非你有一些特定的理由来避免 AOP。您的问题是可以使用 AOP 的经典示例,结果看起来相当不错。这是一个很好的例子来说明如何实现它(如果你还没有读过):Advising transactional operations

    如果 AOP 真的不是一个选项,我会选择 @Lawrence McAlpin 提出的“否则”选项。

    【讨论】:

    • 同意这一点,我不明白为什么要在这种情况下避免 AOP。这是最干净的方法。
    • 这是要走的路,毕竟@Transactional也使用AOP。因此,连接另一个方面将是最好和最简单的事情。
    • 一定要使用 AOP。正如@Sean 指出的那样,您已经在使用带有@Transactional 的Spring AOP,并且Spring 特别支持pointcut expressions that target annotations,因此您可以告诉它运行每个@Transactional 方法而无需额外工作。
    • 谢谢。没有避免AOP的根本原因,只是个人喜好和过去的一些不好的经历!我倾向于为同步要求编写一个方面,因为它似乎符合 AOP 最擅长的,即真正的横切。对于“在事务提交时做某事”的要求,我喜欢 Tomasz 提到的回调解决方案。
    【解决方案2】:

    查看TransactionSynchronization回调接口。 Spring 可以原生地通知您事务发生了什么。

    【讨论】:

    • 这对 Tomasz 的消息发布要求非常有用,谢谢。实际上,它可能也是我们遇到的其他几个长期存在的问题的解决方案,这很棒。
    【解决方案3】:

    我会使用TransactionTemplate(您的选项 4)并在这种情况下以编程方式控制事务的范围。

    否则,您可以将方法中的逻辑移出到单独的服务中,使该新服务为@Transactional,从当前方法中删除@Transactional,然后使用您的 pre- 和 post 包围对新服务的调用- 交易逻辑。我也采用了这种方法,但是对于这样的要求,我更喜欢programmatic transaction management,因为我认为它更干净,而且,正如您所提到的,服务调用服务(只有第一个服务需要)感觉就像一个hackish解决方法。

    【讨论】:

      【解决方案4】:

      如果密钥作为方法调用的一部分被传递,那么您可以使用 java ReentrantLock 来完成这项工作。它更简单、更简洁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-31
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多