spring对事务的支持

/ Spring / 没有评论 / 438浏览

上几篇中我们主要介绍了有关数据库事务相关的知识,在这一篇中,我们将重点了解一下,在spring中是怎么对事务进行支持的。在其它的文章中我们知道spring DAO为了支持不同的持久化技术,于是提供了模板类的方式使之支持不同的持久化技术,那么spring的事务管理也是一样的,它也是采用了这种方式,于是就提供了 TransactionTemplate模板类。在spring中我们可以使用TransactionTemplate模板类,及事务回调TransactionCallback就可以通过编码的方式实现事务管理,并且无须关注资源获取、释放、事务同步和异常处理等操作。

spring事务管理的好处是声明式事务管理,也就是说可以通过IOC配置中指定边界和事务属性,这样spring会自动在指定的事务边界上应用事务属性。

在spring的事务管理中,主要有3个接口,他们分别是:PlatformTransactionManager、TransactionDefinition、TransactionStatus。他们3个具体的关联关系如下:

TIM截图20171017153747.png

下面我们详细了解一下上面3个接口的具体作用。

TransactionDefinition:用户描述事务的隔离级别、超时时间、是否为只读事务和事务传播规则等控制事务具体行为的事务属性。PlatformTransactionManager根据TransactionDefinition提供的事务属性配置信息创建事务,并用TransactionStatus描述这个事务的激活事务的状态。在上面我们介绍过TransactionDefinition用来描述事务的相关属性,那么下面我们具体看一下在TransactionDefinition中都包括哪些事务属性。

TransactionStatus:TransactionStatus表示的是事务的具体运行状态。也就是与通过TransactionStatus可以获取到事务运行期的状态信息,也可以通过该接口间接的回滚事务。这是因为该接口继承了SavepointManager,而SavepointManager接口又支持JDBC3.0中新增的保存点的分段事务控制能力。下面我们简单了解一下SavepointManager中所包括的方法。

除了上述已有的方法外,TransactionStatus还扩展了以下SavepointManager中没有的方法:

PlatformTransactionManager:在其它的文章中使我们知道JDBC的事务只能提交或者回滚。在spring中PlatformTransactionManager的作用就是做上述功能的。下面我们看一下PlatformTransactionManager中的所涉及到的方法及其作用。

上面我们介绍了spring中有关事务的主要接口,下面我们继续了解一下,在spring中这些接口的具体实现,实际上spring为不同的持久化技术都提供了不同的实现,相关的实现类如下:

TIM截图20171018162257.png

spring就是通过这此实现类进而实现spring对事务的管理的,介绍了这么多,我们来看一下在spring中到底怎么用代码的方式也就是声明式事务管理。

<!-- 数据源配置, 使用 Druid数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass
<property name="driverClassName" value="com.mysql.jdbc.Driver" />-->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- 基本属性 urluserpassword -->
<property name="url" value="${druid.url}" />
<property name="username" value="${druid.username}" />
<property name="password" value="${druid.password}" />

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${druid.initialSize}" />
<property name="minIdle" value="${druid.minIdle}" />
<property name="maxActive" value="${druid.maxActive}" />

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${druid.maxWait}" />

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />

<property name="validationQuery" value="${druid.validationQuery}" />
<property name="testWhileIdle" value="${druid.testWhileIdle}" />
<property name="testOnBorrow" value="${druid.testOnBorrow}" />
<property name="testOnReturn" value="${druid.testOnReturn}" />

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!-- 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池-->
<property name="dataSource" ref="dataSource" />
</bean>

这样我们的数据源就支持事务管理了。