Spring 事务管理—下篇

  上篇借剖析Spring事务管理详细讲解了事务在数据库层面的表现形式,有了数据库事务相关方面的基础,接下来可以更好地理解Spring事务管理模板。Spring 事务管理的本质就是对数据库事务的支持,其底层使用JDBC的事务管理机制,利用其提供的功能来完成对数据库事务的操作。其实不使用Spring也可以实现事务,如下:

public void handle(){
    // 建立连接
    Connection con = DriverManager.getConnection();
    try{
      	// 自动提交设为false
    	con.setAutoCommit(false);
    	
    	// 提交事务
    	con.commit();
    }catch(Exception e){
        // 发生异常,回滚事务
        con.rollback();
    }finally{
        // 关闭连接
        con.close();
    }
}

  Spring 事务框架的所有代码都在org.springframework:spring-tx包中,Spring提供了一个统一的事务抽象,换言之无论是JTA、Mybatis、Hibernate,还是JDBC。在Spring中都使用一个统一的事务编程模型,典型的面向接口编程,真正意思上无论底层事务框架是什么,对外暴露的入口就这么一个。
  Spring 事务管理框架有三个核心接口,PlatformTransactionManager、TransactionStatus和TransactionDefinition。PlatformTransactionManager接口依赖于TransactionStatus和TransactionDefinition接口对事务进行操作。

TransactionDefinition

  TransactionDefinition接口定义了符合Spring的事务隔离级别和基于类似于EJB CMT属性的事务传播级别,Spring支持的事务是需要当前数据库支持才能有效。

事务隔离级别

  Spring除提供支持SQL标准的隔离级别:读未提交(ISOLATION_READ_UNCOMMITTED = 1)、读提交(ISOLATION_READ_COMMITTED = 2)、可重复读(ISOLATION_REPEATABLE_READ = 4)和串行化(ISOLATION_SERIALIZABLE = 8)之外,还提供了一个默认的隔离级别(ISOLATION_DEFAULT = -1),所谓的默认其实就是Spring选择当前数据库的默认隔离级别,如是Mysql就是可重复读、如是Oracle就是读已提交。

  • 读未提交,当前事务还没提交时,事务中做的操作就可以被别的事务看到。
  • 读提交,只有当前事务提交以后,事务中做的操作才对其它事务所见。
  • 可重复读,当前事务在执行过程中无论何时看到的数据状态,都跟事务刚启动时看到的一样。
  • 串行化,是最严格的隔离级别,会对写和读都加锁,如遇锁冲突必须等待锁释放才能继续操作。

  以上四个隔离级别与数据库规范的隔离级别一致。但是需要注意的是,隔离级别越高,意味着数据库事务并发执行性能越差。

事务传播级别

  Spring提供的事务传播级别主要控制事务方法间调用,事务的表现形式。简单来讲就是一个事务方法调用另一个事务方法,这两个事务方法之间事务的表现形式,比如二者共用一个事务还是开启新的事务等等。Spring在事务传播级别上一共定义了七种,PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_NEW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER和PROPAGATION_NESTED。

  • PROPAGATION_REQUIRED,支持当前事务,如果当前有事务则使用当前事务,没有则新建事务,简单来说,多个事务方法间调用使用同一个事务。Spring默认的事务传播方式。
  • PROPAGATION_SUPPORTS,支持当前事务,如果当前有事务则使用当前事务,没有就以非事务方式执行。
  • PROPAGATION_MANDATORY,支持当前事务,并且在执行过程中必须有事务定义,如没有事务就直接抛出异常。
  • PROPAGATION_REQUIRES_NEW,支持当前事务,如果当前有事务就挂起,新方法以新建事务的形式执行,简单来说,多个事务发方法间调用使用不同的事务。
  • PROPAGATION_NOT_SUPPORTED,不支持当前事务,如果当前有事务就挂起,执行完后恢复挂起事务。
  • PROPAGATION_NEVER,不支持当前事务,如果当前方法存在事务,就直接抛出异常。
  • PROPAGATION_NESTED,嵌套事务,如果当前存在事务,就直接嵌套在当前事务中。如果不存在事务,就新建一个事务执行。对嵌套事务来说,内部事务回滚不会影响外部事务的提交;但是外部事务回滚会直接将内部事务一起回滚。
超时

  在TransactionDefinition中还定义了一个事务超时时间,默认为数据库的默认超时时间(TIMEOUT_DEFAULT = -1)。事务超时就是事务执行的一个定时器,如果在指定的时间内没有执行完毕,就会自动回滚整个事务段,并中断正在执行的事务,这样的设计就是为了避免长事务的存在。

isReadOnly

  可以通过TransactionDefinition中的isReadOnly方法来判断在当前事务中是否只能读取数据,如果是只读,那么在当前事务中操作写数据就会直接以抛异常的形式来结束当前事务段。

TransactionStatus

  TransactionStatus主要提供当前事务的事务状态,以供事务管理器控制事务是否回滚、是否完成和是否是新事务等等,具体定义如下,hasSavepoint、isNewTransaction、setRollbackOnly、isRollbackOnly和isCompleted。

  • hasSavepoint,当前事务段是否存在恢复点。
  • isNewTransaction,当前事务是否是新事务。
  • setRollbackOnly,设置当前事务只回滚,不提交。
  • isRollbackOnly,当前事务是否回滚。
  • isCompleted,当前事务是否已经完成。

PlatformTransactionManager

  PlatformTransactionManager是Spring事务框架的核心接口,应用程序可以直接使用PlatformTransactionManager,但是又不是主要用于API,应用程序将可以使用事务模板(TransactionTemplate)或者AOP来使用其对事务进行管理。
  要想快速实现事务管理,可以直接继承抽象类AbstractPlatformTransactionManager的方式来实现,因为AbstractPlatformTransactionManager已经提供事务传播行为和事务同步处理,子类就只需要实现对事务特定状态的模板方法,如:doBegin,doSuspend等等。同时Spring还默认提供了支持JDBC的DataSourceTransactionManager实现、支持JPA的JpaTransactionManager、支持JTA的JtaTransactionManager和支持Hibernate的HibernateTransactionManager等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐只乐之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值