Spring with JPA - 如果没有定义事务上下文,则会失败

时间:2014-11-27 11:18:01

标签: spring hibernate jpa transactions spring-transactions

我想要求每个JPA调用都发生在@Transactional上下文中,如果我忘记了该注释,JPA应该抛出异常而不是为每个调用创建隐式事务。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

您问题的一部分更容易回答" JPA应该抛出异常,而不是为每次调用创建隐式事务"。您已了解transaction propagation levels

MANDATORY
          Support a current transaction, throw an exception if none exists.
NESTED
          Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
NEVER
          Execute non-transactionally, throw an exception if a transaction exists.
NOT_SUPPORTED
          Execute non-transactionally, suspend the current transaction if one exists.
REQUIRED
          Support a current transaction, create a new one if none exists.
REQUIRES_NEW
          Create a new transaction, suspend the current transaction if one exists.
SUPPORTS
          Support a current transaction, execute non-transactionally if none exists.

REQUIRED 是默认值,您搜索的语义符合 MANDATORY 。这可以通过在类级别上使用@Transactional(propagation = Propagation.MANDATORY)轻松配置,因为您希望展示此行为的所有bean(DAO层bean是常见的嫌疑人,因为它们不应该是事务所有者,而是始终执行在更大的背景下。)

要回答的棘手问题是如何在实际省略@Transactional时强制执行。省略注释并不能保证任何事情,可能是通过AOP添加了事务语义。或者该课程根本不管理交易。

我肯定会建议将 REQUIRED 保持为默认值,并通过始终使用正确的传播级别声明@Transactional来调整传播级别。

但是,要尝试回答省略位,您可以在spring配置中全局更改默认传播级别,例如

<tx:advice id="txAdvice">
     <tx:attributes>
         <tx:method name="*" propagation="MANDATORY"/>
     </tx:attributes>
 </tx:advice>

通过这样做,你可以有效地翻转硬币,并为你没有用@Transactional(propagation = PROPAGATION.REQUIRED);

标记的所有方法获得例外