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 CMT相熟的所有事务流传选项。要理解无关Spring中事务流传的语义的信息,请参阅事务流传。
  • 隔离:此事务与其余事务的工作隔离的水平。例如,此事务是否看到其余事务未提交的写入?
  • 超时:该事务在超时之前将运行多长时间,并由根底事务根底构造主动回滚。
  • 只读状态:当代码读取但不批改数据时,能够应用只读事务。在某些状况下,例如应用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实现通常须要理解其工作环境:JDBCJTAHibernate等。

TransactionManager实现通常须要理解其工作环境:JDBCJTAHibernate等。以下示例显示了如何定义本地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。以下示例显示了JTAJNDI查找:

<?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名称空间中的<jndi-lookup />标记。无关更多信息,参考JEE Schema。

你还能够轻松应用Hibernate本地事务,如以下示例所示。在这种状况下,你须要定义一个Hibernate LocalSessionFactoryBean,你的利用程序代码可应用该Hibernate LocalSessionFactoryBean获取Hibernate Session实例。

DataSource bean定义与先前显示的本地JDBC示例类似,因而在以下示例中未显示。

如果通过JNDI查找数据源(由任何非JTA事务管理器应用)并由Java EE容器治理,则该数据源应该是非事务性的,因为Spring框架(而不是Java EE容器)治理事务。

在这种状况下,txManager bean是HibernateTransactionManager类型。就像DataSourceTransactionManager须要援用数据源一样,HibernateTransactionManager须要援用SessionFactory。以下示例申明了sessionFactorytxManager 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,则无论应用哪种数据拜访技术(无论是JDBCHibernate JPA或任何其余受反对的技术),事务管理器定义都应该雷同。这是因为JTA事务是全局事务,它能够征用任何事务资源。

在所有这些状况下,无需更改利用程序代码。你能够仅通过更改配置来更改事务的治理形式,即便更改意味着从本地事务转移到全局事务,反之亦然。

作者

集体从事金融行业,就任过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就任于某银行负责对立领取零碎建设。本身对金融行业有强烈的喜好。同时也实际大数据、数据存储、自动化集成和部署、散布式微服务、响应式编程、人工智能等畛域。同时也热衷于技术分享创建公众号和博客站点对常识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!

博客地址: http://youngitman.tech

CSDN: https://blog.csdn.net/liyong1...

微信公众号:

技术交换群: