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