一:事务的特性
原子性:事务最基本的操作单元,要么全部成功,要么全部失败,不会结束在中间某个环节。
一致性:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态,如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
隔离性:在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。
持久性:只要事务成功结束,它对数据库所做的更新就必须永久保存下来
二:事务的传播行为
当多个事务同时存在的时候,spring如何处理这些事务的行为
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。
我们常用的是1和2
三:事务在spring中的配置
(1)基于 TransactionProxyFactoryBean的声明式事务管理
<!-- 事务管理器 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务代理工厂 -->
<!-- 生成事务代理对象 -->
<bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="dataSourceTransactionManager"></property>
<property name="target" ref="buyStockService"></property>
<property name="transactionAttributes">
<props>
<!-- 主要 key 是方法
ISOLATION_DEFAULT 事务的隔离级别
PROPAGATION_REQUIRED 传播行为
-->
<prop key="add*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
<!-- -Exception 表示发生指定异常回滚,+Exception 表示发生指定异常提交 -->
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
</props>
</property>
</bean>
(2)基于 @Transactional 的声明式事务管理
<!-- 事务管理器 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
在需要控制的类或方法中使用注解@Transactionl propagation:传播特性(REQUIRED|SUPPORTS)readOnly:是否只读(true|false)
(3)基于 Aspectj AOP配置事务
1 <!-- 配置spring的事务管理 -->
2
3 <!-- 1.声明事务管理器,交给spring管理 -->
4 <!-- DataSourceTransactionManager 这个事务管理是基于datasource进行的事务管理
5 创建DataSourceTransactionManager的过程中,需要一个dataSource
6 -->
7 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
8 <property name="dataSource" ref="dataSource"></property>
9 </bean>
10
11 <!-- 2.使用tx的命名空间 -->
12
13 <!-- 3.配置事务通知
14 tx:advice
15 id:事务通知的唯一标识
16 transaction-manager:事务管理器
17 -->
18 <tx:advice id="txAdvice" transaction-manager="transactionManager">
19 <!-- 配置事务 -->
20 <tx:attributes>
21 <!-- 配置使事务生效的方法:name指定的是需要控制事务的方法名(支持通配符)
22 * :代表所有方法
23 get* : 匹配所有已get开头的方法
24 优先级:已get*为主
25
26 name:事务增强的方法名
27 propagation:事务的传播行为
28 read-only:是否只读
29 -->
30 <tx:method name="*" propagation="REQUIRED" read-only="false"/>
31 <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
32 </tx:attributes>
33 </tx:advice>
34
35 <!-- 4.配置aop -->
36 <aop:config>
37 <!-- 配置拦截的类和方法 -->
38 <aop:pointcut expression="execution(* cn.itcast.service..*.*(..))" id="pt1"/>
39 <!-- 配置事务通知和切入点表达式之间的关系
40 aop:advisor
41 advice-ref:事务通知的引用
42 pointcut-ref:切入点表达式的引用
43 -->
44 <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
45 </aop:config>