对事务的学习总体来讲应该蕴含以下几个局部:

  1. 事务的概念:数据库层面的,简略理解什么是事务,以及隔离级别、事务的提交、回滚、保留点等基本概念。
  2. 动静代理以及Spring AOP,是Spring框架实现事务管制的底层技术根底。
  3. Spring框架事务的实现形式。
  4. Spring框架事务实现的底层原理。

能够循序渐进逐渐学习,也能够独自学习其中某一部分,然而只有全副彻底把握了,能力对事务有一个全局的理解。

一般来讲,程序员实现事务管制有两种抉择:编程式事务、申明式事务。从代码编写的角度讲,编程式事务太麻烦,当初用的很少了,20年前的程序员绝大部分用的都是编程式事务,十分麻烦,须要本人获取连贯、开启事务、提交或回滚事务、敞开连贯等。

申明式事务是基于AOP实现的,当初JAVA世界的绝大部分我的项目都是基于Spring框架实现的,Spring框架、尤其是Springboot框架对事务管理的反对十分敌对,应用非常简单。

Spring框架实现事务管制其实非常简单,次要的注解只有两个:

  1. @EnableTransactionManagement
  2. @Transactional

@EnableTransactionManagement注解是负责在配置类中关上Spring的事务管理性能,@Transactional是具体负责开启及实现事务管制的。从利用层面来讲,@Transactional是学习的重点。

@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Transactional {    @AliasFor("transactionManager")    String value() default "";    @AliasFor("value")    String transactionManager() default "";    String[] label() default {};    Propagation propagation() default Propagation.REQUIRED;    Isolation isolation() default Isolation.DEFAULT;    int timeout() default -1;    String timeoutString() default "";    boolean readOnly() default false;    Class<? extends Throwable>[] rollbackFor() default {};    String[] rollbackForClassName() default {};    Class<? extends Throwable>[] noRollbackFor() default {};    String[] noRollbackForClassName() default {};}

@Transactional的重要属性包含:

  1. 事务流传机制Propagation
  2. 隔离级别isolation
  3. 期待超时工夫timeout
  4. 回滚条件rollbackFor
  5. 不回滚条件noRollbackFor

其实Spring事务管理是重度依赖于数据库底层的反对的,尤其是相似隔离级别、期待超时工夫等概念,都是间接依赖于数据库底层去实现的,Spring事务管理其实什么都不须要干,只须要把配置好的属性传递给数据库连贯、交给数据库去实现即可。

而事务流传机制Propagation与其余个性不同,是spring框架事务管理性能的重头戏。事务流传机制负责管制不同事务产生的时候,下层事务与上层事务之间的关系。

Spring定义了以下7种事务流传机制:

REQUIRED

Support a current transaction, create a new one if none exists. Analogous to EJB transaction attribute of the same name.This is the default setting of a transaction annotation.

须要启用事务,以后不存在事务的话,就创立一个新事务,如果存在事务的话,则退出。

这是Spring的默认流传机制。

比方事务管制的经典案例银行转账交易:转账交易由转出和转入两局部性能组成,如果咱们依照如下形式实现的话:

@Transactionalpublic void transfer(Acct acct1,Acct acct2){    withdrawl(acct2);     deposit(acct1);}@Transactional(propagation=Propagation.REQUIRED)public void deposit(){    acct1.deposit();}@Transactional(propagation=Propagation.REQUIRED)public void withdrawl(){   acct2.wiwithdrawl();}

转出和转入办法就必须要启用事务、事务流传机制能够设置为REQUIRED,那么在转出交易调用的时候,因为transfer办法曾经开启了一个事务,所以,转出办法withdrawl不再开启新事物、而是应用曾经存在的事务,同样,转入办法deposit也应用该事务。这样,转出交易和转入交易就被蕴含在了同一个事务中,可能实现要么全副胜利、要么全副失败的交易指标。

SUPPORTS

Support a current transaction, execute non-transactionally if none exists. Analogous to EJB transaction attribute of the same name.Note: For transaction managers with transaction synchronization, SUPPORTS is slightly different from no transaction at all, as it defines a transaction scope that synchronization will apply for. As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) will be shared for the entire specified scope. Note that this depends on the actual synchronization configuration of the transaction manager.See Also:org.springframework.transaction.support.AbstractPlatformTransactionManager.setTransactionSynchronization

以后如果曾经开启了事务的话,则退出,如果没有曾经开启的事务的话,也无所谓,以后办法不开启事务。

MANDATORY

Support a current transaction, throw an exception if none exists. Analogous to EJB transaction attribute of the same name.

以后办法被调用的时候必须有事务,如果没有曾经开启的事务的话,就不干,抛异样。

下面银行转账交易,也能够采纳MANDATORY。

REQUIRES_NEW

Create a new transaction, and suspend the current transaction if one exists. Analogous to the EJB transaction attribute of the same name.NOTE: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to org.springframework.transaction.jta.JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available to it (which is server-specific in standard Java EE).See Also:org.springframework.transaction.jta.JtaTransactionManager.setTransactionManager

启用新事务,如果以后曾经存在一个事务的话,则挂起该事务。

被挂起的事务不会受到开启的新事务执行后果的影响,无论新事务被提交还是被回滚。

NOT_SUPPORTED

Execute non-transactionally, suspend the current transaction if one exists. Analogous to EJB transaction attribute of the same name.NOTE: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to org.springframework.transaction.jta.JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available to it (which is server-specific in standard Java EE).See Also:org.springframework.transaction.jta.JtaTransactionManager.setTransactionManager

不启用事务,如果以后曾经存在一个事务的话则挂起以后事务。

NEVER

Execute non-transactionally, throw an exception if a transaction exists. Analogous to EJB transaction attribute of the same name.

不启用事务,如果以后曾经存在一个事务的话就抛出异样。

NESTED

Execute within a nested transaction if a current transaction exists, behave like REQUIRED otherwise. There is no analogous feature in EJB.Note: Actual creation of a nested transaction will only work on specific transaction managers. Out of the box, this only applies to the JDBC DataSourceTransactionManager. Some JTA providers might support nested transactions as well.See Also:org.springframework.jdbc.datasource.DataSourceTransactionManager

嵌套事务,如果以后曾经存在一个事务的话,则行为相似于REQUIRED。留神:嵌套事务仅针对特定的事务管理器,须要特定事务管理器的反对,是否失效取决于JDBC数据源的事务管理器。

嵌套事务的理论含意是:如果以后存在一个事务的话,则保留以后事务的savepoint(保留点),并退出事务,如果以后不存在事务的话,就启用一个新事务。

嵌套事务理论应用了数据库的savepoint,须要数据库反对savepoint,如果数据库不反对savepoint,那么这个NESTED也就不会失效。

savepoint的意思对以后事务曾经执行的数据库操作记录一个保留点,新办法退出事务后,如果执行胜利则一起提交,如果执行失败则只回滚新办法的操作,不回滚保留点以前的数据库操作。

以上Spring提供的7种事务流传机制,咱们应该都有所理解。然而,理论利用场景中能用到的,或者用的比拟多的,也就REQUIRED、以及REQUIRED_NEW。个别状况下REQUIRED足够满足需要了,有些利用框架须要记录操作日志,审计用,不管操作胜利还是失败都须要记录。这种状况下,REQUIRED_NEW即可。