Spring核心篇章: Spring 5 中文解析之核心篇-IoC容器 Spring 5 中文解析核心篇-IoC容器之依赖关系 Spring 5 中文解析核心篇-IoC容器之Bean作用域 Spring 5 中文解析核心篇-IoC容器之自定义Bean性质 Spring 5 中文解析核心篇-IoC容器之BeanDefinition继承与容器拓展点 Spring 5 中文解析核心篇-IoC容器之基于注解的容器配置 Spring 5 中文解析核心篇-IoC容器之类路径扫描和组件管理 Spring 5 中文解析核心篇-IoC容器之JSR330标准注解 Spring 5 中文解析核心篇-IoC容器之基于Java容器配置 Spring 5 中文解析核心篇-IoC容器之Environment抽象 Spring 5 中文解析核心篇-IoC容器之ApplicationContext与BeanFactory Spring 5 中文解析核心篇-IoC容器之Resources Spring 5 中文解析核心篇-IoC容器之数据校验、数据绑定和类型转换 Spring 5 中文解析核心篇-IoC容器之SpEL表达式 Spring 5 中文解析核心篇-IoC容器之AOP编程(上) ") Spring 5 中文解析核心篇-IoC容器之AOP编程(下) Spring 5 中文解析核心篇-IoC容器之Spring AOP API Spring测试篇章: Spring 5 中文解析测试篇-Spring测试 Spring 5 中文解析核心篇-集成测试之概要和集成测试注解 Spring 5 中文解析核心篇-集成测试之TestContext(上) Spring 5 中文解析核心篇-集成测试之TestContext(中) Spring 5 中文解析测试篇-集成测试之TestContext(下) Spring 5 中文解析测试篇-Spring MVC测试框架 Spring 5 中文解析测试篇-WebTestClient Spring存储篇章: Spring 5 中文解析数据存储篇-Spring框架的事物支持模型的优势 完整 电子书地址
1.2 理解Spring框架事物抽象
Spring事务抽象的关键是事务策略的概念。事务策略由
TransactionManager
定义,特别是用于命令式事务管理的
org.springframework.transaction.PlatformTransactionManager
接口和用于响应式事务管理的
org.springframework.transaction.ReactiveTransactionManager
接口。以下清单显示了
PlatformTransactionManager
API的定义:
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
尽管你可以从应用程序代码中以
编程方式使用它,但它主要是一个服务提供接口(SPI)。由于
PlatformTransactionManager
是接口,因此可以根据需要轻松对其进行模拟或存根。它与
JNDI
之类的查找策略无关。与Spring框架IoC容器中的任何其他对象(或bean)一样,定义了
PlatformTransactionManager
实现。这一优点使Spring框架事务成为值得抽象的,即使在使用
JTA
时也是如此。与直接使用
JTA
相比,你可以更轻松地测试事务代码。
同样,为了与Spring的理念保持一致,可以由任何
PlatformTransactionManager
接口方法抛出的
TransactionException
未检查异常(也就是说,它扩展了
java.lang.RuntimeException
类)。事物基础架构故障几乎总是致命的。在极少数情况下,应用程序代码实际上可以从事务失败中恢复,应用程序开发人员仍然可以选择捕获和处理
TransactionException
。实际一点是,开发人员没有被迫这样做。
getTransaction(..)
方法根据
TransactionDefinition
参数返回
TransactionStatus
对象。如果当前调用堆栈中存在匹配的事务,则返回的
TransactionStatus
可能表示一个新事务或一个现有事务。后一种情况的含义是,与Java EE事务上下文一样,
TransactionStatus
与执行线程相关联。
从Spring框架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
熟悉的所有事务传播选项。要了解有关Spring中事务传播的语义的信息,请参阅 事务传播 。CMT
- 隔离:此事务与其他事务的工作隔离的程度。例如,此事务能否看到其他事务未提交的写入?
- 超时:该事务在超时之前将运行多长时间,并由基础事务基础结构自动回滚。
- 只读状态:当代码读取但不修改数据时,可以使用只读事务。在某些情况下,例如使用
时,只读事务可能是有用的优化。Hibernate
这些设置反映了标准的事物概念。如有必要,请参考讨论事务隔离级别和其他核心事务概念的资源。了解这些概念对于使用Spring框架或任何事务管理解决方案至关重要。
TransactionStatus
接口为事务代码提供了一种控制事务执行和查询事务状态的简单方法。这些概念应该很熟悉,因为它们对于所有事务API都是通用的。以下清单显示了
TransactionStatus
接口:
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
等。
TransactionManager
JDBC
JTA
Hibernate
等。以下示例显示了如何定义本地
PlatformTransactionManager
实现(在这种情况下,使用纯
JDBC
)。
你可以通过创建类似于以下内容的bean来定义
JDBC
数据源:
<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>
然后,相关的
PlatformTransactionManager
Bean定义将引用
DataSource
定义。它应类似于以下示例:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
如果你在Java EE容器中使用
JTA
,则可以使用通过
JNDI
获得的容器
DataSource
以及Spring的
JtaTransactionManager
。以下示例显示了
JTA
和
JNDI
查找:
<?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>
JtaTransactionManager
不需要了解数据源(或任何其他特定资源),因为它使用了容器的全局事务管理基础结构。
dataSource
bean的先前定义使用jee名称空间中的标记。有关更多信息,参考 JEE Schema
你还可以轻松使用
Hibernate
本地事务,如以下示例所示。在这种情况下,你需要定义一个
Hibernate
LocalSessionFactoryBean
,你的应用程序代码可使用该
Hibernate
LocalSessionFactoryBean
获取
Hibernate
Session
实例。
DataSource
bean定义与先前显示的本地
JDBC
示例相似,因此在以下示例中未显示。
如果通过查找数据源(由任何非
JNDI
事务管理器使用)并由Java EE容器管理,则该数据源应该是非事务性的,因为Spring框架(而不是Java EE容器)管理事务。
JTA
在这种情况下,
txManager
bean是
HibernateTransactionManager
类型。就像
DataSourceTransactionManager
需要引用数据源一样,
HibernateTransactionManager
需要引用
SessionFactory
。以下示例声明了
sessionFactory
txManager
bean:
<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
和Java EE容器管理的
JTA
事务,则应使用与前面的
JDBC
JTA
示例相同的
JtaTransactionManager
,如以下示例所示:
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
,则无论使用哪种数据访问技术(无论是
JTA
JDBC
Hibernate
或任何其他受支持的技术),事务管理器定义都应该相同。这是由于
JPA
事务是全局事务,它可以征用任何事务资源。
JTA
在所有这些情况下,无需更改应用程序代码。你可以仅通过更改配置来更改事务的管理方式,即使更改意味着从本地事务转移到全局事务,反之亦然。
作者
个人从事金融行业,就职过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就职于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!
博客地址:
http://youngitman.techCSDN:
https://blog.csdn.net/liyong1028826685微信公众号:

技术交流群: