一、概述
Spring 事务概述二、框架
接口框架三、接口
Spring事务管理涉及的接口如下:
接口与具体实现者Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
四、属性
事务管理器接口PlatformTransactionManager通过getTransaction(TransactionDefinition definition)方法来得到事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。
public interface TransactionDefinition{
intgetPropagationBehavior(); // 返回事务的传播行为
intgetIsolationLevel();// 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据
intgetTimeout();// 返回事务必须在多少秒内完成
booleanisReadOnly();// 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的
}
事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面
事务属性的5个方面1、传播行为
Spring定义了七种传播行为:
PROPAGATION_REQUIRED 0 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是Spring默认的事务的传播。
PROPAGATION_SUPPORTS 1 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 2 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 3 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 4 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 5 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 6 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
具体的说, 假设事务传播属性为PROPAGATION_REQUIRED,一般来说将事务设置在service层,那么service层需要调用其他service的时候,那么就可以保证这两个操作在同一个事务中。
事务传播行为类型2、隔离规则
用来解决并发事务时出现的问题,其使用TransactionDefinition中的静态变量来指定
ISOLATION_DEFAULT 使用后端数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE 最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的
可以使用DefaultTransactionDefinition类的setIsolationLevel(TransactionDefinition. ISOLATION_READ_COMMITTED)来指定隔离级别,其中此处表示隔离级别为提交读
也可以使用或setIsolationLevelName(“ISOLATION_READ_COMMITTED”)方式指定,其中参数就是隔离级别静态变量的名字,但不推荐这种方式
3、事务只读
将事务标识为只读,只读事务不修改任何数据;
对于JDBC只是简单的将连接设置为只读模式,对于更新将抛出异常;
对于一些其他ORM框架有一些优化作用,如在Hibernate中,Spring事务管理器将执行“session.setFlushMode(FlushMode.MANUAL)”
即指定Hibernate会话在只读事务模式下不用尝试检测和同步持久对象的状态的更新。
如果使用设置具体事务管理的validateExistingTransaction属性为true(默认false),将确保整个事务传播链都是只读或都不是只读
4、事务超时
设置事务的超时时间,单位为秒,默认为-1表示使用底层事务的超时时间
使用如setTimeout(100)来设置超时时间,如果事务超时将抛出org.springframework.transaction.TransactionTimedOutException异常并将当前事务标记为应该回滚,即超时后事务被自动回滚
可以使用具体事务管理器实现的defaultTimeout属性设置默认的事务超时时间,如DataSourceTransactionManager. setDefaultTimeout(10)
5、回滚规则
spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务
默认配置下,Spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务
如何改变默认规则:
让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
五、事务状态
PlatformTransactionManager接口的getTransaction()的方法得到的是TransactionStatus接口的一个实现,这个接口的内容如下:
public interface TransactionStatus
{
boolean isNewTransaction();// 是否是新的事物
boolean hasSavepoint();// 是否有恢复点
void setRollbackOnly();// 设置为只回滚
boolean isRollbackOnly();// 是否为只回滚
boolean isCompleted;// 是否已完成
}
可以发现这个接口描述的是一些处理事务提供简单的控制事务执行和查询事务状态的方法,在回滚或提交的时候需要应用对应的事务状态
六、实现方式
1、编程式
对应用代码侵入性较大,现已较少使用
2、声明式
声明式事务管理是Spring的一大亮点,利用AOP技术将事务管理作为切面动态织入到目标业务方法中,让事务管理简单易行。两者的共同点是都提供事务管理信息的元数据(数据源、事务管理器都是必须的,一般通过XML的Bean配置)
数据源、事务管理器的Bean配置2.1 XML配置
XML配置事务控制2.2 注解
注解事务控制七、参考资料
1、https://www.jianshu.com/p/05b70834dafe
2、https://www.jianshu.com/p/b697b1cf6eef
网友评论