声明式事务源码
编码式事务源码
一、 事务的概念
1. 概念
全有或全无的操作被称为事务。事务允许你将几个操作组合成一个要么全部反生要么全部不发生的工作单元。
2. 特性
原子性:确保事务中的操作全部反生或者全部不发生
一致性:
隔离性:事务允许多个用户对相同的数据进行操作,每个用户的操作不会与其他用户纠缠在一起。
持久性:一旦事务完成,事务的结果应该持久化。
原子性和隔离性保证了事务的一致性
二、 Spring对事务管理的支持
1. 声明式事务管理:(基于AOP)有助于用户将操作与事务规则进行解耦
2. 编码式事务管理:允许用户在代码中精确定义事务的边界,即它的开始和结束完全取决于你的需求。
三、 选择事务管理器
Spring不直接管理事务,而是提供了多种事务管理器,将事务管理的职责委托给其他持久化机制所提供的平台相关的事务实现。
Mybatis事务
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
四、 声明式事务
1. 传播行为:定义了事务的边界
PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
一般情况下都是选择PROPAGATION_REQUIRED
隔离级别:定义了一个事务可能受其他并发事务影响的程度。
只读:如果事务只对后端的数据库进行读操作,数据库可以利用事务的只读特性来进行一些特定的优化。(数据库会应用它认为合适的优化措施),只有具备启动一个新的事务的传播行为有用。
- 事务超时:因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要地占用数据库资源。可以声明一个事务,在特定的秒数后自己回滚,而不是等待其结束。
- 回滚规则:这些规则定义了哪些异常会导致是事务回滚而哪些不会。
在xml中配置事务
a.在XML中定义事务
<tx:advice id="userTxAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="find*" propagation="SUPPORTS"/>
<tx:method name="get*" propagation="SUPPORTS"/>
<tx:method name="select*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
tx:advice:只是定义了一个AOP通知,用于把事务边界通知给方法。但是这只是事务通知,而不是事务性切面。中没有声明哪些Bean应该被通知—需要一个切点(如下)来做这件事。
<aop:config>
<aop:pointcut id="pc" expression="execution(public * com.lixing.scm.test.service.*.*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice" />
</aop:config>
tx:attributes:元素中,该元素包含了一个或多个
tx:method:元素为某个name属性(使用通配符)指定的方法定义事务参数
b.定义注解驱动的事务
<tx:annotation-driven transaction-manager="transactionManager" />
五、 编码式事务
• 使用 TransactionTemplate
• 直接使用一个 PlatformTransactionManager 实现
如果你选择编程式事务管理,Spring小组推荐使用 TransactionTemplate。 第二种方法则类似使用JTA的 UserTransaction API (除了异常处理的部分稍微简单
1. TansactionTemplate:
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
<property name="transactionManager" ref="transactionManager" />
</bean>
2.PlatFormTransactionManager:
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>