一般来说,对事务的学习应该包括以下几个部分:事务的概念:在数据库层面,简单了解什么是事务,以及基本的隔离级别,事务提交,回滚、保存点等概念。动态代理和SpringAOP是Spring框架实现事务控制的底层技术基础。Spring框架事务的实现。Spring框架事务实现的底层原理。可以循序渐进地学习,也可以单独学习一部分,但只有全部掌握透彻,才能对交易有一个整体的认识。一般来说,程序员有两种实现事务控制的选择:编程式事务和声明式事务。从代码编写的角度来看,程序化事务过于繁琐,现在已经很少使用了。20年前的程序员大多使用程序化事务,非常麻烦。需要获取连接、开启事务、提交或回滚事务、关闭连接等。声明式事务是基于AOP实现的。JAVA界的大部分项目都是基于Spring框架实现的。Spring框架,尤其是Springboot框架,对事务管理的支持非常友好,非常好用。Spring框架中事务控制的实现其实很简单。主要的注解只有两个:@EnableTransactionManagement@Transactional@EnableTransactionManagement注解负责在配置类中开启Spring的事务管理功能,@Transactional具体负责开启和实现事务控制。从应用层面来说,@Transactional是学习的重点。@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic@interfaceTransactional{@AliasFor("transactionManager")Stringvalue()默认"";@AliasFor("value")StringtransactionManager()default"";字符串[]标签()默认{};传播propagation()defaultPropagation.REQUIRED;隔离isolation()defaultIsolation.DEFAULT;整数超时()默认-1;字符串timeoutString()默认"";booleanreadOnly()默认false;类[]rollbackFor()默认{};String[]rollbackForClassName()默认{};类[]noRollbackFor()默认{};String[]noRollbackForClassName()default{};}@Transactional的重要属性包括:事务传播机制Propagationisolationlevelisolationwaitingfortimeout超时回滚条件rollbackFor无回滚条件noRollbackFor其实Spring事务管理是非常依赖底层支持的数据库的,尤其像隔离级别,等待超时等概念,直接依赖数据库底层来实现,Spring的东西其实事务管理什么都不用做,只需要将配置好的属性传递给数据库连接,交给数据库完成即可。事务传播机制Propagation不同于其他特性,是spring框架事务管理功能的重头戏。事务传播机制负责控制不同事务发生时上层事务和下层事务之间的关系。Spring定义了以下七种事务传播机制:REQUIREDS支持当前事务,如果不存在则创建一个新事务。类似于同名的EJB事务属性。这是事务注释的默认设置。需要启用事务,目前不存在事务,如果有事务,则新建一个事务,如果有事务,则加入。这是Spring默认的传播机制。比如交易控制的经典案例,银行转账交易:转账交易包含两个函数:转出和转入。如果我们这样实现:@Transactionalpublicvoidtransfer(Acctacct1,Acctacct2){withdrawl(acct2);deposit(acct1);}@Transactional(propagation=Propagation.REQUIRED)publicvoiddeposit(){acct1.deposit();}@Transactional(propagation=Propagation.REQUIRED)publicvoidwithdrawl(){acct2.wiwithdrawl();}转出和转入方法必须启用交易,并且交易传播机制可以设置为REQUIRED。那么调用转出交易的时候,因为转出方法已经开启了一个交易,所以转出方法withdrawl不再开始一个新的东西,而是使用一个已经存在的交易,同样,转出方法deposit也是使用这个交易。这样,转出交易和转入交易被包含在同一个交易中,可以达到要么全部成功要么全部失败的交易目标。SUPPORTS支持当前事务,如果不存在则以非事务方式执行。类似于同名的EJB事务属性。注意:对于具有事务同步的事务管理器,SUPPORTS与根本没有事务略有不同,因为它定义了一个将适用的事务范围。因此,相同的资源(JDBC连接、Hibernate会话等)将在整个指定范围内共享。请注意,这取决于事务管理器的实际同步配置。另见:org.springframework。transaction.support.AbstractPlatformTransactionManager.setTransactionSynchronization如果事务已经开启,则加入。如果没有已经开启的交易,则无所谓。当前方法不打开事务。MANDATORY支持当前事务,如果不存在则抛出异常。类似于同名的EJB事务属性。调用当前方法时必须有事务。如果没有已经开启的事务,则不做,并抛出异常。以上银行转账交易也可以使用MANDATORY。REQUIRES_NEW创建一个新事务,如果存在则暂停当前事务。类似于同名的EJB事务属性。注意:实际的事务暂停不会在所有事务管理器上开箱即用。这尤其适用于org.springframework.transaction.jta.JtaTransactionManager,它需要javax.transaction.TransactionManager可用(在标准JavaEE中特定于服务器)。另请参阅:org.springframework.transaction。jta.JtaTransactionManager.setTransactionManager启动一个新的事务,或者如果事务已经存在则暂停该事务。挂起的事务不会受到新事务开启的执行结果的影响,无论新事务是提交还是回滚。NOT_SUPPORTED以非事务方式执行,如果存在则挂起当前事务。类似于同名的EJB事务属性。注意:实际的事务暂停不会在所有事务管理器上开箱即用。这尤其适用于org.springframework.transaction.jta.JtaTransactionManager,它需要javax.transaction.TransactionManager可用(在标准JavaEE中是特定于服务器的)。另请参阅:org.springframework.transaction.jta.JtaTransactionManager.setTransactionManager不是enabledTransaction,如果已经有事务,则暂停当前事务。NEVER以非事务方式执行,如果存在事务则抛出异常。NESTED如果当前事务存在,则在嵌套事务中执行,否则表现得像REQUIRED。EJB中没有类似的功能。注意:实际创建嵌套事务只会对特定的事务管理器起作用。开箱即用,这仅适用于JDBCDataSourceTransactionManager。某些JTA提供程序也可能支持嵌套事务。另请参阅:org.springframework.jdbc.datasource.DataSourceTransactionManager嵌套事务,如果已经存在事务,则行为类似于REQUIRED。注意:嵌套事务只针对特定的事务管理器,需要特定事务管理器的支持。是否生效取决于JDBC数据源的事务管理器。嵌套事务的实际含义是:如果当前有事务,则保存当前事务的保存点(savepoint)并加入事务,如果当前没有事务,则开始新的事务。嵌套事务实际上使用的是数据库的savepoint,需要数据库支持savepoint。如果数据库不支持savepoint,那么这个NESTED就不会生效。保存点是指为当前事务执行过的数据库操作记录一个保存点。新的方法添加到事务中后,如果执行成功,会一起提交。如果执行失败,只会回滚新方法的操作,不会回滚保存点之前的数据库操作。.上面Spring提供的七种事务传播机制大家应该都明白了。但是,在实际应用场景中能够用到,或者用得比较多的,就是REQUIRED和REQUIRED_NEW。一般来说,REQUIRED足以满足需求。一些应用框架需要记录操作日志以供审计,无论操作成功与否。在这种情况下,REQUIRED_NEW就可以了。Previous事务的概念NextSpring事务框架的TransactionDefinition
