Spring 简明教程

Spring - Transaction Management

数据库事务是一系列操作,它们被当作一个工作单元执行。这些操作应要么全部完成,要么完全不产生任何效果。事务管理是面向 RDBMS 的企业应用程序的重要组成部分,以确保数据完整性和一致性。事务的概念可以用以下四项关键特性来描述 ACID

  1. Atomicity − 事务应作为一个操作单元来处理,这意味着操作序列要么全部成功,要么全部失败。

  2. Consistency − 这表示了数据库的引用完整性一致性、表中的唯一主键等。

  3. Isolation − 可能有多个事务同时处理相同的数据集。应将每个事务隔离起来以防止数据损坏。

  4. Durability − 一旦事务完成,该事务的结果必须变为永久性并且不能因系统故障而被删除。

真正的 RDBMS 数据库系统将为每个事务保证所有四个特性。使用 SQL 向数据库发出的事务的简单视图如下 −

  1. 使用开始事务命令开始事务。

  2. 使用 SQL 查询执行各种删除、更新或插入操作。

  3. 如果所有操作都成功,则执行提交,否则回滚所有操作。

Spring 框架在不同基础事务管理 API 的基础上提供了抽象层。Spring 的事务支持旨在通过向 POJO 添加事务功能来提供 EJB 事务的替代方案。Spring支持基于编程和声明的事务管理。EJB 需要应用程序服务器,但 Spring 事务管理可以在不需要应用程序服务器的情况下实现。

Local vs. Global Transactions

本地事务特定于单个事务性资源(例如 JDBC 连接),而全局事务则可以跨越多个事务性资源(例如分布式系统中的事务)。

当应用程序组件和资源位于一个站点时,本地事务管理在集中计算环境中可能很有用,并且事务管理仅涉及在单台机器上运行的本地数据管理器。本地事务更容易实现。

在所有资源都分布在多个系统中的分布式计算环境中需要全局事务管理。在这种情况下,需要在本地和全局级别执行事务管理。跨多个系统执行分布式或全局事务,并且其执行要求全局事务管理系统和所有相关系统的所有本地数据管理程序之间的协调。

Programmatic vs. Declarative

Spring支持两种类型的事务管理−

  1. Programmatic transaction management − 这意味着您必须借助编程来管理事务。这样会赋予您极大的灵活性,但难以维护。

  2. Declarative transaction management − 这意味着您将事务管理与业务代码分开。您只使用批注或基于 XML 的配置来管理事务。

声明性事务管理优于编程事务管理,尽管它不如编程事务管理灵活,而后者允许您通过代码控制事务。但作为一种横切关注点,声明性事务管理可以通过 AOP 方法模块化。Spring 通过 Spring AOP 框架支持声明性事务管理。

Spring Transaction Abstractions

Spring 事务抽象的关键由 org.springframework.transaction.PlatformTransactionManager 接口定义,如下所示 −

public interface PlatformTransactionManager {
   TransactionStatus getTransaction(TransactionDefinition definition);
   throws TransactionException;

   void commit(TransactionStatus status) throws TransactionException;
   void rollback(TransactionStatus status) throws TransactionException;
}

Sr.No

Method & Description

1

TransactionStatus getTransaction(TransactionDefinition definition) 此方法根据指定传播行为,返回当前活动事务或创建一个新事务。

2

void commit(TransactionStatus status) 此方法提交给定事务,并考虑其状态。

3

void rollback(TransactionStatus status) 此方法对给定事务执行回滚。

TransactionDefinition 是 Spring 中事务支持的核心接口,定义如下 −

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

Sr.No

Method & Description

1

int getPropagationBehavior() 此方法返回传播行为。Spring 提供了所有 EJB CMT 中熟悉的事务传播选项。

2

int getIsolationLevel() 此方法返回事务与其他事务的工作隔绝程度。

3

String getName() 此方法返回事务的名称。

4

int getTimeout() 此方法以秒为单位返回事务必须完成的时间。

5

boolean isReadOnly() 此方法返回事务是否为只读。

以下是隔离级别的可能值 −

Sr.No

Isolation & Description

1

TransactionDefinition.ISOLATION_DEFAULT 这是默认隔离级别。

2

TransactionDefinition.ISOLATION_READ_COMMITTED 表示会阻止脏读;可能发生不可重复读和幻读。

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED 表示可能发生脏读、不可重复读和幻读。

4

TransactionDefinition.ISOLATION_REPEATABLE_READ 表示会阻止脏读和不可重复读;可能发生幻读。

5

TransactionDefinition.ISOLATION_SERIALIZABLE 表示会阻止脏读、不可重复读和幻读。

以下是传播类型的可能值 −

Sr.No.

Propagation & Description

1

TransactionDefinition.PROPAGATION_MANDATORY 支持当前事务;如果不存在当前事务,则会引发异常。

2

*TransactionDefinition.PROPAGATION_NESTED *如果存在当前事务,则在嵌套事务中执行。

3

*TransactionDefinition.PROPAGATION_NEVER *不支持当前事务;如果存在当前事务,则会引发异常。

4

*事务定义.PROPAGATION_NOT_SUPPORTED*不支持当前事务;相反,始终非事务性地执行。

5

TransactionDefinition.PROPAGATION_REQUIRED 支持当前事务;如果不存在事务,则创建一个新事务。

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW 创建一个新事务,如果存在当前事务,则暂停该事务。

7

TransactionDefinition.PROPAGATION_SUPPORTS 支持当前事务;如果不存在事务,则非事务性地执行。

8

TransactionDefinition.TIMEOUT_DEFAULT 使用基础事务系统的默认超时,如果没有支持超时,则不使用。

事务状态接口为事务代码提供了一种简单的方法来控制事务执行和查询事务状态。

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

Sr.No.

Method & Description

1

boolean hasSavepoint() 此方法返回此事务是否在内部携带保存点,即是否已基于保存点创建为嵌套事务。

2

boolean isCompleted() 此方法返回此事务是否已完成,即是否已提交或回滚。

3

boolean isNewTransaction() 如果当前事务是新的,则此方法返回 true。

4

boolean isRollbackOnly() 此方法返回事务是否已标记为仅回滚。

5

void setRollbackOnly() 此方法将事务设置为仅回滚。