1、基础概念
事务是指一条或多条sql语句构成的工作单元,在这个工作单元内所有的sql语句相互依赖,要么同时提交,要么同时失败。
2、事务边界
1、自动提交
在设置自动提交事务的范围内,每执行一条sql语句则提交一次。
2、手动提交
在设置手动提交事物的范围内,所有的sql语句都会放到一个事务单元内,要么同时提交,要么失败回滚。
3、事务分类
事务共有三种实现方式,但都需要配置部分相同的配置文件。
<!--扫描并实例化需要添加的依赖-->
<context:component-scan base-package="com.zhang.spring"/>
<!--配置源数据库-->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="此处省略。。。"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--事务管理器-->
<bean id="transactonManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager>
<constructor-org name="dataSource" ref=datasource"/>
</bean>
<!--数据库模板-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<consrtuctro-org ref="datasource"/>
</bean>
1、声明型事务
需要额外配置事务方法和事务传播特性
<!--事务方法-->
<aop:config>
<!--拦截需要执行事务的方法-->
<aop:pointcut id="transactionMethod" expression="execution(* com.zhang.*(..))"/>
<!--绑定方法与事务处理-->
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionMethod"/>
</aop:config>
<!--事务传播特性-->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--名称为insert的方法添加事务-->
<tx:method name="insert"/>
<!--其他方法的数据库连接方式设置只读-->
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
2、注解型事务
<!--提供注解支持-->
<tx:annotation-driven transaction-manager="transactionManager"/>
//添加事务
@Transactional
public int insert1(String name, int age) {}
//设置为只读
@Transactional(readOnly = true)
public int insert2(String name, int age) {}
3、编译型事务
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<constructor-arg ref="transactionManager"/>
</bean>
public int insert(String name, int age) {
return transactionTemplate.execute(new TransactionCallback<Integer>() {
@Override
public Integer doInTransaction(TransactionStatus status) {
//do something
return 0;
}
});
}
4、传播特性
把事务从数据层剥离出来,转嫁到逻辑层之上。在应用环境中环境层业务非常复杂导致逻辑层之间需要频繁的相互调用。传播特性就是为了解决该问题提出。
1、PROPAGATION_REQUIRED 必须(有就用,没就创建)
如果当前线程中存在已启用的事务,则支持当前事务(不再开启其他事务,公用事务)
如果当前线程中不存在已启用的事务,则开启全新的事务。
2、PROPAGATION_SUPPURTS 支持(有就用,没就不用)
如果当前线程中存在已启用的事务,则支持当前事务
如果当前线程中不存在已启用的事务,则非事务执行
3、PROPAGATION_MANDATORY 强制(有就用,没有报错)
如果当前线程中存在已启用的事务,则支持当前事务
如果当前线程中不存在已启用的事务,则抛出异常
4、PROPAGATION_NEVER 从不(有就报错,没就执行)
如果当前线程中存在已启用的事务,直接抛出异常
如果当前线程中不存在已启用的事务,则非事务执行
5、PROPAGATION_REQUIRES_NEW 需要全新事务(无论是否有,都创建新事务)
如果当前线程中存在已启用的事务,首先挂起当前运行中的事务,然后开启全新事务,最终执行完毕后释放挂起事务。
如果当前线程中不存在已启用的事务,则开启全新的事务
优先级较高(适合紧急情况)
6、PROPAGATION_NOT_SUPPORTED 不支持事务(无则执行,有则挂起执行)
如果当前线程中存在已启用的事务,首先挂起运行中的事务挂起,然后非事务执行,最终执行完毕后释放挂起的事务。
如果当前线程中不存在已启用的事务,则非事务执行
7、PROPAGATION_NESTED 嵌套
如果第一个事务执行失败,程序直接结束。
如果第一个事务执行成功,事务提交到缓存数据中(脏数据)。
如果第二个事务执行成功,则先提交第二个事务再提交第一个事务。
如果第二个事务执行失败,则先回滚第二个事务,在提交第一个事务。