| 
         此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10!  | 
    
| 
         此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10!  | 
    
Spring 事务抽象的关键是事务策略的概念。一个
事务策略由 定义,具体来说是命令式
事务管理和反应式接口
事务管理。以下列表显示了 API 的定义:TransactionManagerorg.springframework.transaction.PlatformTransactionManagerorg.springframework.transaction.ReactiveTransactionManagerPlatformTransactionManager
public interface PlatformTransactionManager extends TransactionManager {
	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
}
这主要是一个服务提供程序接口 (SPI),尽管您可以从应用程序代码中以编程方式使用它。因为是一个接口,所以它可以很容易地被嘲笑或存根为
必要。它与查找策略(如 JNDI)无关。 实现的定义与任何其他对象(或 Bean)类似
在 Spring Framework IoC 容器中。仅此一项优势就使 Spring Framework
事务是一个有价值的抽象,即使你使用JTA也是如此。你可以测试
事务代码比直接使用 JTA 要容易得多。PlatformTransactionManagerPlatformTransactionManager
同样,根据 Spring 的哲学,可以抛出的
通过接口的任何方法都未选中(该
是,它扩展了类)。交易基础设施
失败几乎总是致命的。在极少数情况下,应用程序代码实际上可以
从事务失败中恢复,应用程序开发人员仍然可以选择捕获
和句柄 .突出的一点是,开发人员不会被迫这样做。TransactionExceptionPlatformTransactionManagerjava.lang.RuntimeExceptionTransactionException
该方法返回一个对象,具体取决于参数。返回的可能表示
新交易或可以表示现有交易,如果交易匹配
存在于当前调用堆栈中。后一种情况的含义是,与
Jakarta EE 事务上下文中,a 与
执行。getTransaction(..)TransactionStatusTransactionDefinitionTransactionStatusTransactionStatus
从 Spring Framework 5.2 开始,Spring 还为
使用反应式类型或 Kotlin 协程的响应式应用程序。以下
列表显示了由以下定义的交易策略:org.springframework.transaction.ReactiveTransactionManager
public interface ReactiveTransactionManager extends TransactionManager {
	Mono<ReactiveTransaction> getReactiveTransaction(TransactionDefinition definition) throws TransactionException;
	Mono<Void> commit(ReactiveTransaction status) throws TransactionException;
	Mono<Void> rollback(ReactiveTransaction status) throws TransactionException;
}
反应式事务管理器主要是一个服务提供商接口(SPI),
尽管您可以从您的
应用程序代码。因为是一个接口,所以可以很容易地
必要时嘲笑或存根。ReactiveTransactionManager
该接口指定:TransactionDefinition
- 
传播:通常,事务范围内的所有代码都在 该交易。但是,如果出现以下情况,您可以指定行为 当事务上下文已存在时,将运行事务方法。为 例如,代码可以在现有事务中继续运行(常见情况),或者 可以暂停现有事务并创建新事务。Spring 提供 EJB CMT 中熟悉的所有事务传播选项。要阅读 关于 Spring 中事务传播的语义,请参阅事务传播。
 - 
隔离:此事务与其他事务的工作隔离的程度 交易。例如,此事务是否可以查看来自其他事务的未提交写入 交易?
 - 
超时:此事务在超时并自动回滚之前运行的时间 由底层事务基础设施提供。
 - 
只读状态:当代码读取但 不修改数据。在某些情况下,只读事务可能是一个有用的优化 情况,例如使用 Hibernate 时。
 
这些设置反映了标准的事务概念。如有必要,请参阅参考资料 讨论事务隔离级别和其他核心事务概念。 理解这些概念对于使用 Spring 框架或任何 事务管理解决方案。
该接口为事务代码提供了一种简单的方法
控制事务执行并查询事务状态。这些概念应该是
熟悉,因为它们是所有事务 API 通用的。以下列表显示了该接口:TransactionStatusTransactionStatus
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
	@Override
	boolean isNewTransaction();
	boolean hasSavepoint();
	@Override
	void setRollbackOnly();
	@Override
	boolean isRollbackOnly();
	void flush();
	@Override
	boolean isCompleted();
}
无论您选择声明式还是程序化事务管理,在
Spring,定义正确的实现是绝对必要的。
通常通过依赖关系注入来定义此实现。TransactionManager
TransactionManager实现通常需要了解
它们的工作方式:JDBC、JTA、Hibernate 等。以下示例演示如何执行以下操作
定义一个本地实现(在本例中,使用 plain
JDBC.)PlatformTransactionManager
您可以通过创建类似于以下内容的 Bean 来定义 JDBC:DataSource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>
然后,相关的 Bean 定义具有对定义的引用。它应类似于以下示例:PlatformTransactionManagerDataSource
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>
</bean>
如果你在Jakarta EE容器中使用JTA,那么你使用一个容器,获得
通过 JNDI,与 Spring 的 .以下示例
显示了 JTA 和 JNDI 查找版本的样子:DataSourceJtaTransactionManager
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/jee
		https://www.springframework.org/schema/jee/spring-jee.xsd">
	<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
	<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
	<!-- other <bean/> definitions here -->
</beans>
不需要知道 (或任何其他
特定资源),因为它使用容器的全局事务管理
基础设施。JtaTransactionManagerDataSource
Bean 的上述定义使用标记
从命名空间。有关详细信息,请参阅 JEE 架构。dataSource<jndi-lookup/>jee | 
| 如果使用 JTA,那么事务管理器定义应该看起来相同,无论如何 您使用的数据访问技术,无论是 JDBC、Hibernate JPA 还是任何其他支持的技术 科技。这是因为 JTA 事务是全局事务,这 可以登记任何事务性资源。 | 
在所有 Spring 事务设置中,应用程序代码不需要更改。您可以更改 如何仅通过更改配置来管理事务,即使该更改意味着 从本地事务转移到全局事务,反之亦然。
Bean 的上述定义使用标记
从命名空间。有关详细信息,请参阅 JEE 架构。dataSource<jndi-lookup/>jee | 
| 如果使用 JTA,那么事务管理器定义应该看起来相同,无论如何 您使用的数据访问技术,无论是 JDBC、Hibernate JPA 还是任何其他支持的技术 科技。这是因为 JTA 事务是全局事务,这 可以登记任何事务性资源。 | 
休眠事务设置
您还可以轻松使用 Hibernate 本地事务,如以下示例所示。
在这种情况下,您需要定义一个 Hibernate ,其中
应用程序代码可用于获取 Hibernate 实例。LocalSessionFactoryBeanSession
Bean 定义类似于前面所示的本地 JDBC 示例
因此,以下示例中未显示。DataSource
如果 (由任何非 JTA 事务管理器使用) 被查找
JNDI 并由 Jakarta EE 容器管理,它应该是非事务性的,因为
Spring Framework(而不是 Jakarta EE 容器)管理事务。DataSource | 
在本例中,bean 属于 type。在
与需要对 的引用一样,需要对 的引用。以下
示例声明和 Bean:txManagerHibernateTransactionManagerDataSourceTransactionManagerDataSourceHibernateTransactionManagerSessionFactorysessionFactorytxManager
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="mappingResources">
		<list>
			<value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
		</list>
	</property>
	<property name="hibernateProperties">
		<value>
			hibernate.dialect=${hibernate.dialect}
		</value>
	</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
	<property name="sessionFactory" ref="sessionFactory"/>
</bean>
如果使用 Hibernate 和 Jakarta EE 容器管理的 JTA 事务,则应使用
与前面的 JDBC JTA 示例相同,如下所示
示例显示。此外,建议通过其
事务协调器,可能还有它的连接释放模式配置:JtaTransactionManager
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="mappingResources">
		<list>
			<value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
		</list>
	</property>
	<property name="hibernateProperties">
		<value>
			hibernate.dialect=${hibernate.dialect}
			hibernate.transaction.coordinator_class=jta
			hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT
		</value>
	</property>
</bean>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
或者,您可以将 传递给 your 以强制执行相同的默认值:JtaTransactionManagerLocalSessionFactoryBean
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="mappingResources">
		<list>
			<value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
		</list>
	</property>
	<property name="hibernateProperties">
		<value>
			hibernate.dialect=${hibernate.dialect}
		</value>
	</property>
	<property name="jtaTransactionManager" ref="txManager"/>
</bean>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
如果 (由任何非 JTA 事务管理器使用) 被查找
JNDI 并由 Jakarta EE 容器管理,它应该是非事务性的,因为
Spring Framework(而不是 Jakarta EE 容器)管理事务。DataSource |