Spring事务管理-使用基础
2017-09-13 11:50
274 查看
Spring提供的事物管理有两种:
编程式事物(使用TransactionTemplate,粒度控制在代码块,手动提交)声明式事务(XML、注解, 粒度只能控制在public方法)
事务管理是基于数据源的,也就是说mybatis引用的数据源必须和DataSourceTransactionManager引用的数据源一致。这样事务管理才能生效。
Spring 事务特性。
Spring所有的事务管理策略都继承于org.springframework.transaction.PlatformTransactionManager接口
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
一般我们使用的都是DataSourceTransactionManager,也就是基于数据源的事务管理。我们先看看DataSourceTransactionManager的类继承关系:
我们从上面图中看到两个很重要的接口:PlatformTransactionManager 和 InitializingBean 。实现了PlatformTransactionManager说明这个类主要功能是进行事务管理;实现了InitializingBean接口,从bean的生命周期来看,我们知道InitializingBean#afterPropertiesSet() 是在单例的bean的第二阶段,populate属性之后调用的,我们看看DataSourceTransactionManager里面的实现,从下面源码可知,DataSourceTransactionManager进行事务管理的前提是DataSource已经成功注入。
@Override public void afterPropertiesSet() { if (getDataSource() == null) { throw new IllegalArgumentException("Property 'dataSource' is required"); } }
前面介绍了DataSourceTransactionManager与数据源的关系,那么Spring对事务是怎么支持的呢?
TransactionDefinition接口里面定义了事务的隔离级别和事务的传播行为:
Spring中事务隔离级别
::隔离级别::是指若干个并发事务之间的隔离程度,以MySQL为例,我们知道在MySQL中定义了四种事务的隔离级别:1. Read Uncommitted(未提交读)
2. Read Committed(提交读)
3. Repeatable Read(可重复读)(MySQL默认)
4. Serializable(可串行化)
在Spring的事务管理中一样,TransactionDefinition也定义了5种隔离级别
//底层数据库默认的隔离级别,这个与具体数据库有关系 int ISOLATION_DEFAULT = -1; // 未提交读 int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED; // 提交读:只能读取别人commit了的数据 int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED; // 可重复读:存在幻读,不过MySQL通过MVCC解决这个问题 int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ; // 串行化 int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
Spring的事务传播行为
这一点是比较难理解的一点,所谓::事务传播行为::是指:如果在开始当前事务之前,一个事务上下文已经存在了,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition中同样定义了如下几种事务传播行为:
// 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 int PROPAGATION_REQUIRED = 0; // 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 int PROPAGATION_SUPPORTS = 1; // 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 int PROPAGATION_MANDATORY = 2; // 创建一个新的事务,如果当前存在事务,则把当前事务挂起。 int PROPAGATION_REQUIRES_NEW = 3; // 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 int PROPAGATION_NOT_SUPPORTED = 4; // 以非事务方式运行,如果当前存在事务,则抛出异常。 int PROPAGATION_NEVER = 5; // 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行; // 如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。 int PROPAGATION_NESTED = 6;
事务超时时间
所谓::事务超时::就是指:一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。
事务只读属性
只读事务用于客户代码只能读但不修改数据的情形,只读事务用于特定情景下的优化。Spring事务回滚规则
其实也就是在事务内部如果抛出了异常,Spring的事务回滚规则是怎么样的。spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。默认配置:spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。
我们可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。
::@Transactional 注解::
::属性::* transactionManager : 指定使用的事务管理器,这也是注解的默认值
* propagation:事务传播行为
* isolation:事务隔离级别
* readOnly:是否是只读
* timeout:超时时间
* rollbackFor:导致事务回滚的异常类数组
* rollbackForClassName:导致事务回滚的异常类名字数组
* noRollbackFor:不会导致事务回滚的异常类数组
* noRollbackForClassName:不会导致事务回滚的异常类名字数组
::注解作用域::
作用于类以及类方法上。但是只能作用域public方法,因为是基于AOP实现的。
本文涉及的核心类
PlatformTransactionManager 接口以及其子类DataSourceTransactionManager 类
TransactionDefinition
从上文我们可以知道,其实Spring的事务管理其实就是基于DataSource的事务管理,也就是基于数据库的事务原理。
相关文章推荐
- 使用Spring注解方式管理事务与传播行为详解
- 使用Spring 2.0 新特性实现声明式事务管理-基于Annotation
- Spring 下事务管理 - 使用 AOP XML 配置管理(iBatis 为例)
- Spring学习笔记(16)----使用Spring配置文件实现事务管理
- spring 事务管理 1(使用spring的JdbcTemplate访问数据库)
- 使用Spring配置文件实现事务管理
- Spring视频学习(九)使用Spring注解方式管理事务与传播行为详解
- spring使用事务管理时的问题
- Spring 使用注解方式进行事务管理
- Spring 下事务管理-使用AOP @Transactional注解管理
- Java学习之道:纯Hibernate使用-不用spring事务管理
- 使用TransactionScope时出现“与基础事务管理器的通信失败”的错误
- Spring整合hibernate的事务属性介绍以及声明式事务管理 (使用Annotation和xml)
- spring 事务管理 2(spring的事务方法镶嵌使用,事务边界和传播性)没完
- Spring学习笔记(15)----使用Spring注解方式管理事务
- 使用spring实现事务管理(@transactional)的遇到的两个异常:java.lang.noclassdeffounderror:org/objectweb.asm
- 使用spring管理事务的时候,配置文件的主意事项。
- hibernate,spring管理事务中(transaction,JDBC connection,Hibernate Session的使用)
- Spring 无法释放连接的原因:没有使用事务管理!
- Spring使用XML进行声明式的事务管理