此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
程序化事务管理
Spring Framework 提供了两种编程事务管理方法,通过使用:
-
这
TransactionTemplate
或TransactionalOperator
. -
一个
TransactionManager
直接实现。
Spring 团队一般建议将TransactionTemplate
用于程序化
命令式流中的事务管理,以及TransactionalOperator
用于响应式代码。
第二种方法类似于使用 JTAUserTransaction
API,尽管例外
处理不那么麻烦。
使用TransactionTemplate
这TransactionTemplate
采用与其他 Spring 模板相同的方法,例如
这JdbcTemplate
.它使用回调方法(使应用程序代码不必
进行样板采购并发布事务资源)并导致
意图驱动的代码,因为您的代码仅关注什么
你想做。
如下例所示,使用TransactionTemplate 绝对
将您与 Spring 的事务基础设施和 API 相结合。是否为程序化
事务管理是否适合您的开发需求是您做出的决定
必须让自己。 |
必须在事务上下文中运行并显式使用TransactionTemplate
类似于下一个示例。您作为应用程序
developer,可以编写一个TransactionCallback
实现(通常表示为
匿名内部类),其中包含您需要在
交易。然后,您可以传递自定义的实例TransactionCallback
到execute(..)
在TransactionTemplate
.以下示例显示了如何执行此作:
-
Java
-
Kotlin
public class SimpleService implements Service {
// single TransactionTemplate shared amongst all methods in this instance
private final TransactionTemplate transactionTemplate;
// use constructor-injection to supply the PlatformTransactionManager
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method runs in a transactional context
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
// use constructor-injection to supply the PlatformTransactionManager
class SimpleService(transactionManager: PlatformTransactionManager) : Service {
// single TransactionTemplate shared amongst all methods in this instance
private val transactionTemplate = TransactionTemplate(transactionManager)
fun someServiceMethod() = transactionTemplate.execute<Any?> {
updateOperation1()
resultOfUpdateOperation2()
}
}
如果没有返回值,可以使用方便的TransactionCallbackWithoutResult
类
使用匿名类,如下所示:
-
Java
-
Kotlin
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
transactionTemplate.execute(object : TransactionCallbackWithoutResult() {
override fun doInTransactionWithoutResult(status: TransactionStatus) {
updateOperation1()
updateOperation2()
}
})
回调中的代码可以通过调用setRollbackOnly()
提供的方法TransactionStatus
对象,如下所示:
-
Java
-
Kotlin
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();
updateOperation2();
} catch (SomeBusinessException ex) {
status.setRollbackOnly();
}
}
});
transactionTemplate.execute(object : TransactionCallbackWithoutResult() {
override fun doInTransactionWithoutResult(status: TransactionStatus) {
try {
updateOperation1()
updateOperation2()
} catch (ex: SomeBusinessException) {
status.setRollbackOnly()
}
}
})
指定事务设置
您可以指定事务设置(例如传播模式、隔离级别、
超时,依此类推)在TransactionTemplate
以编程方式或以
配置。默认情况下,TransactionTemplate
实例具有默认的事务设置。这
以下示例显示了事务设置的编程自定义
一个特定的TransactionTemplate:
-
Java
-
Kotlin
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
// the transaction settings can be set here explicitly if so desired
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
// and so forth...
}
}
class SimpleService(transactionManager: PlatformTransactionManager) : Service {
private val transactionTemplate = TransactionTemplate(transactionManager).apply {
// the transaction settings can be set here explicitly if so desired
isolationLevel = TransactionDefinition.ISOLATION_READ_UNCOMMITTED
timeout = 30 // 30 seconds
// and so forth...
}
}
以下示例定义了TransactionTemplate
使用一些自定义事务
使用 Spring XML 配置进行设置:
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
<property name="timeout" value="30"/>
</bean>
然后,您可以注入sharedTransactionTemplate
转换为所需的服务。
最后,的实例TransactionTemplate
类是线程安全的,在这种情况下
不要保持任何对话状态。TransactionTemplate
然而,实例确实如此,
维护配置状态。因此,虽然多个类可以共享一个实例
的TransactionTemplate
,如果类需要使用TransactionTemplate
跟
不同的设置(例如,不同的隔离级别),您需要创建
两个不同的TransactionTemplate
实例。
使用TransactionalOperator
这TransactionalOperator
遵循与其他响应式类似的运算符设计
运营商。它使用回调方法(使应用程序代码不必执行
样板获取和释放事务资源),并生成代码
意图驱动,因为您的代码只关注您想要做的事情。
如下例所示,使用TransactionalOperator 绝对
将您与 Spring 的事务基础设施和 API 相结合。是否为程序化
事务管理是否适合您的开发需求是您的决定
让自己。 |
必须在事务上下文中运行并显式使用
这TransactionalOperator
类似于下一个示例:
-
Java
-
Kotlin
public class SimpleService implements Service {
// single TransactionalOperator shared amongst all methods in this instance
private final TransactionalOperator transactionalOperator;
// use constructor-injection to supply the ReactiveTransactionManager
public SimpleService(ReactiveTransactionManager transactionManager) {
this.transactionalOperator = TransactionalOperator.create(transactionManager);
}
public Mono<Object> someServiceMethod() {
// the code in this method runs in a transactional context
Mono<Object> update = updateOperation1();
return update.then(resultOfUpdateOperation2).as(transactionalOperator::transactional);
}
}
// use constructor-injection to supply the ReactiveTransactionManager
class SimpleService(transactionManager: ReactiveTransactionManager) : Service {
// single TransactionalOperator shared amongst all methods in this instance
private val transactionalOperator = TransactionalOperator.create(transactionManager)
suspend fun someServiceMethod() = transactionalOperator.executeAndAwait<Any?> {
updateOperation1()
resultOfUpdateOperation2()
}
}
TransactionalOperator
可以通过两种方式使用:
-
使用项目反应堆类型的运算符样式 (
mono.as(transactionalOperator::transactional)
) -
回调样式适用于所有其他情况 (
transactionalOperator.execute(TransactionCallback<T>)
)
回调中的代码可以通过调用setRollbackOnly()
提供的方法ReactiveTransaction
对象,如下所示:
-
Java
-
Kotlin
transactionalOperator.execute(new TransactionCallback<>() {
public Mono<Object> doInTransaction(ReactiveTransaction status) {
return updateOperation1().then(updateOperation2)
.doOnError(SomeBusinessException.class, e -> status.setRollbackOnly());
}
}
});
transactionalOperator.execute(object : TransactionCallback() {
override fun doInTransactionWithoutResult(status: ReactiveTransaction) {
updateOperation1().then(updateOperation2)
.doOnError(SomeBusinessException.class, e -> status.setRollbackOnly())
}
})
取消信号
在响应式流中,Subscriber
可以取消其Subscription
并停止其Publisher
.Project Reactor 中的运算符,以及其他库中的运算符,例如next()
,take(long)
,timeout(Duration)
,其他人可以发出取消。没有办法
了解取消的原因,是由于错误还是仅仅缺少
兴趣进一步消费。自 5.3 版以来,取消信号会导致回滚。
因此,重要的是要考虑事务下游使用的运算符Publisher
.特别是在Flux
或其他多值Publisher
,
必须使用完整输出才能完成事务。
指定事务设置
您可以为TransactionalOperator
. 默认情况下,TransactionalOperator
实例具有默认事务设置。 这 以下示例显示了特定事务设置的自定义TransactionalOperator:
-
Java
-
Kotlin
public class SimpleService implements Service {
private final TransactionalOperator transactionalOperator;
public SimpleService(ReactiveTransactionManager transactionManager) {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
// the transaction settings can be set here explicitly if so desired
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
definition.setTimeout(30); // 30 seconds
// and so forth...
this.transactionalOperator = TransactionalOperator.create(transactionManager, definition);
}
}
class SimpleService(transactionManager: ReactiveTransactionManager) : Service {
private val definition = DefaultTransactionDefinition().apply {
// the transaction settings can be set here explicitly if so desired
isolationLevel = TransactionDefinition.ISOLATION_READ_UNCOMMITTED
timeout = 30 // 30 seconds
// and so forth...
}
private val transactionalOperator = TransactionalOperator(transactionManager, definition)
}
使用TransactionManager
以下各节将说明命令式事务和响应式事务的编程用法 经理。
使用PlatformTransactionManager
对于命令式事务,您可以使用org.springframework.transaction.PlatformTransactionManager
直接管理您的 交易。 为此,请通过PlatformTransactionManager
你 通过 bean 引用对 bean 使用。然后,通过使用TransactionDefinition
和TransactionStatus
对象,您可以启动事务、回滚和提交。 这 以下示例显示了如何执行此作:
-
Java
-
Kotlin
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// put your business logic here
} catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
val def = DefaultTransactionDefinition()
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName")
def.propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED
val status = txManager.getTransaction(def)
try {
// put your business logic here
} catch (ex: MyException) {
txManager.rollback(status)
throw ex
}
txManager.commit(status)
使用ReactiveTransactionManager
处理响应式事务时,可以使用org.springframework.transaction.ReactiveTransactionManager
直接管理您的 交易。 为此,请通过ReactiveTransactionManager
你 通过 bean 引用对 bean 使用。然后,通过使用TransactionDefinition
和ReactiveTransaction
对象,您可以启动事务、回滚和提交。 这 以下示例显示了如何执行此作:
-
Java
-
Kotlin
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
Mono<ReactiveTransaction> reactiveTx = txManager.getReactiveTransaction(def);
reactiveTx.flatMap(status -> {
Mono<Object> tx = ...; // put your business logic here
return tx.then(txManager.commit(status))
.onErrorResume(ex -> txManager.rollback(status).then(Mono.error(ex)));
});
val def = DefaultTransactionDefinition()
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName")
def.propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED
val reactiveTx = txManager.getReactiveTransaction(def)
reactiveTx.flatMap { status ->
val tx = ... // put your business logic here
tx.then(txManager.commit(status))
.onErrorResume { ex -> txManager.rollback(status).then(Mono.error(ex)) }
}