在@Transactional方法之前和之后执行代码

时间:2011-07-12 13:01:06

标签: java spring

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

  1. 我们需要根据密钥同步对方法的访问。线程需要在事务开始之前阻塞。
  2. 如果事务成功,我们需要在队列上发布消息。
  3. 选项似乎是:

    1. 使用与可在同步块中运行@Transactional方法的服务类似的方法创建一个类,并检查返回然后发布消息(由于AOP代理问题,需要一个单独的类)。呼叫服务的服务并不好,感觉就像是一种解决方法。
    2. 编写一个方面来包装@Transactional AOP,它可以进行同步和消息发布。可能会工作,但宁可避免AOP。
    3. 将交易下移到域图层。由于域方法在不同的工作流程中重复使用,因此当前实现不可取或甚至不可行。
    4. 在服务方法中手动编码交易并废弃@Transactional。
    5. 我认为这是一个相当普遍的要求。可能我错过了一个选项5,这是显而易见的选择!

4 个答案:

答案 0 :(得分:4)

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

如果AOP真的不是一个选项,我会选择@Lawrence McAlpin提出的'其他'选项。

答案 1 :(得分:2)

查看TransactionSynchronization回调界面。 Spring可以原生地通知您交易发生的事情。

答案 2 :(得分:1)

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

否则,您可以将方法中的逻辑移到单独的服务中,创建新服务@Transactional,从当前方法中删除@Transactional,然后使用您的前置和后置将调用包围到新服务 - 交易逻辑。我也采用了这种方法,但我更喜欢programmatic transaction management这样的要求,因为我觉得它更干净,正如你所提到的,呼叫服务的服务(只有第一次服务才需要)才感觉像一个黑客的解决方法。

答案 3 :(得分:0)

如果密钥是作为方法调用的一部分传递的,那么你可以使用java ReentrantLock来完成工作..它更简单&清洁剂。