Spring事务管理机制是如何实现的?
摘要:前言 我们都知道Spring给我们提供了很多抽象,比如我们在操作数据库的过程中,它为我们提供了事务方面的抽象,让我们可以非常方便的以事务方式操作数据库。不管你用JDBC、Mybatis、Hibernate等任何一种方式操作数据库,也不管你使
前言
我们都知道Spring给我们提供了很多抽象,比如我们在操作数据库的过程中,它为我们提供了事务方面的抽象,让我们可以非常方便的以事务方式操作数据库。不管你用JDBC、Mybatis、Hibernate等任何一种方式操作数据库,也不管你使用DataSource还是JTA的事务,Spring事务抽象管理都能很好的把他统一在一起。接下来看一下事务的抽象核心接口
Spring事务抽象
PlatformTransactionManager是事务管理器接口
//事务管理器接口有以下几个接口,获取事务信息,提交和回滚
public interface PlatformTransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
void commit(TransactionStatus var1) throws TransactionException;
void rollback(TransactionStatus var1) throws TransactionException;
}
常见的事务管理器有以下几种
DataSourceTransactionManager
HibernateTransactionManager
JtaTransactionManager
这些管理器都实现了PlatformTransactionManager中的三个接口,实现逻辑略有差别,但是对用户来讲区别不大
定义事务的一些参数:
一些事务的参数在TransactionDefinition.java中,详情如下:
public interface 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;
int PROPAGATION_NESTED = 6;
//默认隔离级别,和数据库的隔离级别一致
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
//默认不超时
int TIMEOUT_DEFAULT = -1;
}
下面两张图对这些参数进行了说明:
7种事务传播特性:
四种事务隔离级别:
在看事务隔离级别前需要先了解下什么是脏读、不可重复读、幻读
脏读: 脏读就是一个事物未提交的数据,被另外一个事务读到了,显然这种情况不可接受
不可重复读: 不可重复读是指在一个事务内,多次读同一数据,前后读取的结果不一致。
幻读: 事务A对表中的一个数据进行了修改,这种修改涉及到表中的全部数据行。同时事务B也修改了这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生操作事务A的用户发现表中还存在没有修改的数据行,就好像发生了幻觉一样
知道了以上几个概念,我们来看看隔离级别:
这里我们可以看到,Spring并不是提供了所有的事务管理的实现,而是提供了标准的事务管理器的操作接口PlatformTransactionManager, 并且规范了其行为,具体的事务实现由各个平台自行实现。这就是Spring的事务抽象。
Spring之编程式事务
Spring提供了TransactionTemplate工具类可以很方便的使用编程式事务。默认情况下TransactionTemplate使用的是DataSourceTransactionManager。
在Spring上下文中,我们不配置TransactionTemplate这个bean,也能获取到TransactionTemplate。比如下面的例子。
