Spring事务提供了两种管理的的方式:编程式事务和声明式事务
简单回顾下事务:
事务:逻辑上的一组操作,组成操作的各个单元,要么全部成功,要么全部失败。
事务特性:
原子性:一个事务包含的各个操作单元不可分割
一致性:事务执行前后数据应当保持一致
隔离性:一个事务的执行不应当受到其他事务的干扰
持久性:事务执行完之后,数据就被持久化到磁盘上
Spring事务管理常用的API:
PlatformTransactionmanager:平台事务管理器
平台事务管理器:是一个接口,是spring用于管理事务的真正的对象
DataSourceTransactionManager:底层使用JDBC管理事务的时候的具体实现类
HibernateTransactionManager:底层使用Hibernate管理事务时候的具体实现类
TransactionDefinition:事务定义信息
事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读
TransactionStatus:事物的状态
事务状态:用于记录事务管理过程中,事务的状态的对象。
事务管理API的关系:
spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中,就会产生各种状态,将这些状态及信息记录到事务状态的对象中。
Spring事务的传播行为
spring事务传播行为主要负责业务层之间互相调用的复杂问题。spring会提供7种事务的传播行为,大概可以分为三类:
- 假设有A/B两个方法,各自包含不同的事务操作。
- 保证多个操作在同一个事务中
- PROPAGATION_REQUIRED (常用):默认值,B事务所在的方法调用A事务所在的方法,如果A中有事务,则使用A中的事务(包含B事务),如果A没有,创建一个新的事务,将操作包含进来
- PROPAGATION_MANDATORY :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
- PROPAGATION_SUPPORTS :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
- 保证多个操作不在同一个事务中
- PROPAGATION_REQUIRES_NEW (常用):B事务所在的方法调用A事务所在的方法,如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含B自身操作。如果A中没有事务,创建一个新事务,包含B自身操作。
- PROPAGATION_NEVER :如果A中有事务,报异常。
- PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理
- 嵌套式事务
- PROPAGATION_NESTED (常用):嵌套事务,B事务所在的方法调用A事务所在的方法,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置(A执行前),也可以回滚到保存点。
Spring的事务管理
声明式事务管理:
xml方式声明事务管理:
<!--配置service--> <bean id="accountservice" class="com.demo1.tx.AccountServiceImp"> <property name="accountDao" ref="accountdao"/> </bean> <!--配置dao--> <bean id="accountdao" class="com.demo1.dao.AccountDaoImp"> <property name="dataSource" ref="datasource"/> </bean> <!--1、配置数据库连接池,引入数据库配置文件--> <context:property-placeholder location="classpath:com/demo1/jdbc.properties"/> <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--2、配置事务管理器--> <bean id="transactionManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"/> </bean> <!--3、配置事务的增强:需要注入一个事务管理器属性--> <tx:advice transaction-manager="transactionManager" id="txadvice"> <tx:attributes> <!--事务管理的规则--> <tx:method name="*" propagation="REQUIRED"/> <!--表示设置所有方法的传播行为为required--> </tx:attributes> </tx:advice> <!--4、aop的配置--> <aop:config> <aop:pointcut id="pointcut1" expression="execution(* com.demo1.tx.AccountServiceImp.*(..))"/> <!--配置切入点为AccountServiceImp类下面的所有方法--> <!-- <aop:aspect/> 多个切入点和多个通知的组合--> <!--一个切入点和一个通知的组合--> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/> </aop:config>
注解方式声明事务管理:
- 配置事务管理器
- <bean id="transactionManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"/> </bean>
- 开启事务注解
- <tx:annotation-driven transaction-manager="transactionManager"/>
- 业务层方式上添加注解
@Transactional(propagation = Propagation.REQUIRED,readOnly = true)