敖胤

绳锯木断,水滴石穿;聚沙成塔,集腋成裘。

导航

Spring事务管理

Spring事务的本质就是对数据库事务的支持,没有数据库事务,Spring是无法提供事务功能的。

Spring只提供统一的事务管理接口,具体实现都是由数据库自己实现的,数据库事务的提交和回滚是通过bin log或者undo log实现的。

Spring会在事务开始时,根据当前设置的隔离级别,调整数据库的隔离级别,由此保持一致。

一、Spring事务管理方式

Spring支持编程式事务管理和声明式事务管理两种方式。

  • 编程式事务:使用TransactionTemplate实现。
  • 声明式事务:使用AOP方式实现。

声明式事务的优点是不需要在业务代码中掺杂事务管理代码,只需要在配置文件中声明或通过@Transactional注解即可实现;但是最细控制粒度为方法,无法作用到代码块级别。

二、Spring事务传播机制

Spring事务的传播机制,指存在多个事务时,Spring如何管理这些事务的行为。

事务传播机制使用的是简单的ThreadLocal实现的;因此,若是在新线程中调用,事务的传播实际是失效的。

Spring定义的事务传播机制分类:

public enum Propagation {
	/**
	 * Support a current transaction, create a new one if none exists.
	 * <p>This is the default setting of a transaction annotation.
	 * (默认方式)如果当前存在事务,则加入,否则,新建一个
	 */
   REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

   /**
    * Support a current transaction, execute non-transactionally if none exists.
    * 当前存在事务,则加入,否则以非事务方式运行
    */
   SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

   /**
    * Support a current transaction, throw an exception if none exists.
    * 当前存在事务,则加入,否则抛出异常
    */
   MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

   /**
    * Create a new transaction, and suspend the current transaction if one exists.
    * 创建一个新的事务,若当前存在事务,则挂起
    */
   REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

   /**
    * Execute non-transactionally, suspend the current transaction if one exists.
    * 以非事务方式执行,若当前存在事务,则挂起
    */
   NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

   /**
    * Execute non-transactionally, throw an exception if a transaction exists.
    * 以非事务方式执行,若当前存在事务,则抛异常
    */
   NEVER(TransactionDefinition.PROPAGATION_NEVER),

   /**
    * Execute within a nested transaction if a current transaction exists, behave like {@code REQUIRED} otherwise. 
    * <p>Note: Actual creation of a nested transaction will only work on specific transaction managers.
    * 当前存在事务,则以嵌套事务的方式运行;否则按照REQUIRED的方式执行(创建一个新事务)
    */
   NESTED(TransactionDefinition.PROPAGATION_NESTED);

    ...
}

三、Spring事务隔离级别

public enum Isolation {

   /**
    * Use the default isolation level of the underlying datastore.
    * 使用链接数据库的默认隔离级别
    */
   DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),

   /**
    * A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur. 
    * This level allows a row changed by one transaction to be read by another transaction before any changes in that row have been committed (a "dirty read"). 
    * 读未提交,允许事务在执行过程中,读取其他事务未提交的数据。会造成“脏读”,实际上是什么都没解决。
    */
   READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),

   /**
    * A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur. 
    * This level only prohibits a transaction from reading a row with uncommitted changes in it.
    * 读已提交,允许事务在执行过程中,读取其他事务已经提交的数据。可避免“脏读”
    */
   READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),

   /**
    * A constant indicating that dirty reads and non-repeatable reads areprevented; phantom reads can occur. 
    * This level prohibits a transaction from reading a row with uncommitted changes in it, and it also prohibits the situation where one transaction reads a row, a second transaction alters the row, and the first transaction rereads the row, getting different values the second time (a "non-repeatable read").
    * 可重复读,在同一个事务内,任意时刻的查询结果都是一致的。解决“不可重复读”问题
    */
   REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),

   /**
    * A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented. 
    * This level includes the prohibitions in
    * 串行化,所有事务依次执行,解决所有问题。
    */
   SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
    
    ...

}

posted on 2021-04-21 17:48  敖胤  阅读(183)  评论(0)    收藏  举报