Spring事务简单介绍
相关类介绍
PlatformTransactionManager
-
PlatformTransactionManager: (平台)事务管理器
-
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
-
TransactionStatus: 事务运行状态
PlatformTransactionManager
三个方法
public interface PlatformTransactionManager {
// 根据指定的传播行为,返回当前活动的事务或创建一个新事务
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
// 使用事务目前的状态提交事务
void commit(TransactionStatus var1) throws TransactionException;
// 对执行的事务进行回滚
void rollback(TransactionStatus var1) throws TransactionException;
}
TransactionDefinition
事务管理器接口 PlatformTransactionManager 通过 getTransaction(TransactionDefinition definition) 方法来得到一个事务,这个方法里面的参数是 TransactionDefinition类 ,这个类就定义了一些基本的事务属性。
public interface TransactionDefinition {
// 返回事务的传播行为
int getPropagationBehavior();
// 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据
int getIsolationLevel();
// 返回事务必须在多少秒内完成
int getTimeout();
// 返回是否优化为只读事务。
boolean isReadOnly();
//返回事务的名字
@Nullable
String getName();
// TransactionDefinition 接口中定义了五个表示隔离级别的常量:
/*
*
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
}
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
一、事务隔离级别(定义了一个事务可能受其他并发事务影响的程度):
并发事务带来的问题
隔离级别
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
/**
* 使用后端数据库默认的隔离级别,
* Mysql 默认采用的 REPEATABLE_READ隔离级别
* Oracle 默认采用的 READ_COMMITTED隔离级别.
*/
int ISOLATION_DEFAULT = -1;
/**
* 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
*/
int ISOLATION_READ_UNCOMMITTED = 1;
/**
* 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
*/
int ISOLATION_READ_COMMITTED = 2;
/**
* 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
*/
int ISOLATION_REPEATABLE_READ = 4;
/**
* 最高的隔离级别,完全服从ACID的隔离级别。
* 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
* 但是这将严重影响程序的性能。通常情况下也不会用到该级别。
*/
int ISOLATION_SERIALIZABLE = 8;
二、事务传播行为(为了解决业务层方法之间互相调用的事务问题):
// 支持当前事务的情况:
/**
* 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
*/
int PROPAGATION_REQUIRED = 0;
/**
* 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
*/
int PROPAGATION_SUPPORTS = 1;
/**
* 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
*/
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 的值来表示超时时间,其单位是秒。
四、举个简单例子
rollbackFor与IllegalArgumentException 异常回滚
rollback-for
用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。
/**
* 特定异常数据回滚
* @param person 保存数据
* @return
*/
@Override
@Transactional(rollbackFor = {IllegalArgumentException.class})
public Person savePersonWithRollBack(Person person) {
Person p = personRepository.save(person);
String name = "elijah";
if (p.getName().equals(name)) {
// 手动触发异常
throw new IllegalArgumentException(name + "已经存在,数据将回滚");
}
return p;
}
/**
* noRollbackFor 特定异常 数据不会滚
* IllegalArgumentException不合法的参数异常
* @param person
* @return
*/
@Override
@Transactional(noRollbackFor = IllegalArgumentException.class)
public Person savePersonWithoutRollBack(Person person) {
Person p = personRepository.save(person);
String name = "elijah";
if (p.getName().equals(name)) {
throw new IllegalArgumentException(name + "已经存在,数据不会回滚");
}
return p;
}
执行结果

参考内容: 作者:SnailClimb链接:https://juejin.im/post/5b00c52ef265da0b95276091来源:掘金著作权归作者所有。
2019/10/09 于成都
网友评论