此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
回滚声明性事务
上一节概述了如何为
类,通常是服务层类,以声明方式在应用程序中。本节
描述了如何以简单的声明性方式控制事务的回滚
XML 配置中的时尚。有关以声明方式控制回滚语义的详细信息
使用@Transactional
注释,请参阅@Transactional
设置.
向 Spring Framework 的事务基础设施指示的推荐方式
要回滚事务的工作是抛出一个Exception
从代码中
当前在事务的上下文中执行。Spring Framework 的
事务基础设施代码捕获任何未处理的Exception
当它冒泡时
调用堆栈,并确定是否将事务标记为回滚。
在其默认配置中,Spring Framework 的事务基础设施代码
仅在运行时未检查的异常情况下将事务标记为回滚。
也就是说,当抛出的异常是RuntimeException
.
(Error
默认情况下,实例也会导致回滚)。
默认配置还支持 Vavr 的Try
触发方法
事务在返回“Failure”时回滚。
这允许您使用 Try 处理函数式错误并拥有事务
发生故障时自动回滚。有关 Vavr 的 Try 的更多信息,
请参阅官方 Vavr 文档。
以下是如何将 Vavr 的 Try 与事务方法一起使用的示例:
-
Java
@Transactional
public Try<String> myTransactionalMethod() {
// If myDataAccessOperation throws an exception, it will be caught by the
// Try instance created with Try.of() and wrapped inside the Failure class
// which can be checked using the isFailure() method on the Try instance.
return Try.of(delegate::myDataAccessOperation);
}
从 Spring Framework 6.1 开始,还有CompletableFuture
(和一般Future
) 返回值,如果它
在从原始方法返回时异常完成。
这是为了@Async
实际方法实现可能
需要遵守CompletableFuture
签名(自动适应实际的
调用代理的异步句柄@Async
运行时处理),
更喜欢在返回的句柄中公开,而不是重新引发异常:
-
Java
@Transactional @Async
public CompletableFuture<String> myTransactionalMethod() {
try {
return CompletableFuture.completedFuture(delegate.myDataAccessOperation());
}
catch (DataAccessException ex) {
return CompletableFuture.failedFuture(ex);
}
}
从事务方法引发的已检查异常不会导致回滚
在默认配置中。您可以准确配置哪个Exception
类型标记 A
用于回滚的事务,包括通过指定回滚规则检查的异常。
回滚规则
回滚规则确定当给定异常发生时是否应回滚事务 thrown,并且规则基于异常类型或异常模式。 回滚规则可以通过 当使用异常类型定义回滚规则时,该类型将用于匹配
针对抛出的异常的类型及其超级类型,提供类型安全和
避免使用模式时可能发生的任何意外匹配。例如,一个
值 当使用异常模式定义回滚规则时,该模式可以是完全
异常类型的限定类名或完全限定类名的子字符串
(必须是
|
以下 XML 代码片段演示了如何为已选中的
特定应用Exception
类型,通过rollback-for
属性:
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
如果您不希望在抛出异常时回滚事务,您还可以
指定“无回滚”规则。以下示例告诉 Spring Framework 的
事务基础设施来提交伴随事务,即使面对
未处理InstrumentNotFoundException
:
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
当 Spring Framework 的事务基础设施捕获异常并咨询
配置的回滚规则,用于确定是否将事务标记为回滚,
最强匹配规则获胜。因此,在以下配置的情况下,任何
除InstrumentNotFoundException
导致
伴随交易:
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*" rollback-for="Throwable" no-rollback-for="InstrumentNotFoundException"/>
</tx:attributes>
</tx:advice>
您还可以以编程方式指示所需的回滚。虽然简单,但这个过程 具有相当的侵入性,并且将您的代码与 Spring Framework 的事务紧密耦合 基础设施。以下示例演示如何以编程方式指示必需的 反转:
-
Java
-
Kotlin
public void resolvePosition() {
try {
// some business logic...
} catch (NoProductInStockException ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
fun resolvePosition() {
try {
// some business logic...
} catch (ex: NoProductInStockException) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
强烈建议您使用声明性方法进行回滚(如果有的话) 可能。如果您绝对需要,可以使用编程回滚,但它 使用与实现基于 POJO 的干净架构背道而驰。