Spring事务

Spring事务的管理类型分为两种:编程式事务和声明式事务。编程式事务管理,即通过编写代码实现事务管理,包括定义事务的开始,程序正常执行后的事务提交,异常时进行的事务回滚。声明式事务管理,底层是建立在 AOP 的基础之上。其本质是对方法前后进行拦截,在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

Java EE应用的传统事务有两种策略:全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器的JTA支持。局部事务和底层所采用的持久化技术有关,当采用JDBC持久化技术时,需要使用Connection对象来操作事务。

全局事务可以跨多个事务性资源(比如说多个数据库和消息队列);使用局部事务,应用服务器不需要参与事务管理,因此不能保证多个事务性资源的事务正确性。

Spring的事务抽象包括三个主要的接口,即PlatformTransactionManager、TransactionDefinition和TransactionStatus,他们之间的关系如下图:

PlatformTransactionManager负责界定事务边界,是Spring事务的核心组件。TransactionDefinition负责定义事务的相关属性,包括隔离级别、传播行为、超时时间和是否为只读事务。PlatformTransactionManager根据TransactionDefinition的属性定义来开启相关事务。事务开启之后到事务结束期间的事务状态由TransactionStatus负责。

PlatformTransactionManager有三个方法,其源码为:

public interface PlatformTransactionManager{
	//获得事务的方法
	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
	//事务提交方法
	void commit(TransactionStatus status) throws TransactionException;
	//事务回滚方法
	void rollback(TransactionStatus status) throws TransactionException;
}

事务的属性:

事务的属性主要定义在TransactionDefinition中,包括:

  • 事务的隔离级别
  • 事务的传播行为
  • 事务的超时时间
  • 是否为只读事务

事务的隔离级别:

TransactionDefinition内定义了五个常量用于标志可供选择的隔离级别:

  • ISOLATION_DEFAULT:表示使用数据库默认的隔离级别,通常情况下是READ COMMITTED(提交读/不可重复读),但是MySQL的是REPEATABLE READ(可重复读)。
  • ISOLATION_READ_UNCOMMITTED:对应READ UNCOMMITTED(未提交读)隔离级别,会有脏读、不可重复读和幻读问题。
  • ISOLATION_READ_COMMITTED:对应READ COMMITTED(提交读)隔离级别,会有不可重复读和幻读问题。
  • ISOLATION_REPEATABLE_READ:对应REPEATABLE READ(可重复读)隔离级别,会有幻读问题。
  • ISOLATION_SERIALIZABLE:对应SERIALIZABLE(可串行化)隔离级别,可以避免脏读、幻读和不可重复读,但是并行效率最低。

Spring支持4个标准的隔离级别,但最终事务是否以指定的隔离级别执行,则由底层数据资源决定。如果Spring指定的隔离级别当前数据库不支持,则以数据库默认的隔离级别执行。

事务的传播行为:

Spring事务的传播行为表示整个事务处理过程所跨越的业务对象,将以什么样的行为参与事务。比如,当有FoobarService调用FooService和BarService两个方法的时候,FooService的业务方法和BarService的业务方法可以指定它们各自的传播行为。

TransactionDefinition提供了以下七种可供选择的事务传播行为:

  • PROPAGATION_REQUIRED:如果当前存在一个事务,则加入当前事务。如果当前不存在事务,则创建一个新事务。总之,要至少保证在一个事务中运行。通常作为默认的事务传播行为。
  • PROPAGATION_SUPPORTS:如果当前存在事务,则加入当前事务。如果当前不存在事务,则直接执行。
  • PROPAGATION_MANDATORY:强制要求当前存在一个事务,如果当前不存在事务,则直接抛出异常。如果某个方法需要事务支持,但自身又不管理事务提交或回滚,那么比较适用该传播行为。
  • PROPAGATION_REQUIRED_NEW:不管当前是否存在事务,都会创建新的事务。如果当前存在事务,则将当前事务挂起。如果某个业务对象所做的事情不想影响到外层事务,则适合该传播行为。
  • PROPAGATION_NOT_SUPPORT:不支持当前事务,要求在没有事务的情况下执行。如果当前存在事务,当前事务原则上将被挂起,但这要看对应的PlatformTransactionManager实现类是否支持事务的挂起。
  • PROPAGATION_NEVER:永远不需要当前存在事务,如果当前存在事务,则直接抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在当前事务中创建一个嵌套事务。如果当前不存在事务,则创建一个新事务,在新事务中执行。注意与PROPAGATION_REQUIRED_NEW区别,在当前存在事务的情况下,PROPAGATION_NESTED创建的是内嵌事务,是寄生于外层事务的,内部事务的内容也是属于外部事务的内容,其不能独立于外部事务存在,它的地位低于外层事务,并且不会挂起外层事务,内嵌事务运行的时候,外层事务的状态也是active状态。而PROPAGATION_REQUIRED_NEW创建的事务与外部事务是同级的,二者独立存在而互不干扰,并且PROPAGATION_REQUIRED_NEW创建新事务后会将当前事务挂起。该传播行为是Spring独有的。其需要特定的PlatformTransactionManager实现类支持。

TransactionStatus代表事务本身,它提供了简单的控制事务执行和查询事务状态的方法,其源码:

public interface TransactionStatus{
	//判断事务是否为新建的事务
	boolean isNewTransaction();
	//设置事务回滚
	void setRollbackOnly();
	//查询事务是否已有回滚标志
	boolean isRollbackOnly();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值