Spring - 事务管理



数据库事务是一系列被视为单个工作单元的操作。这些操作应该要么完全完成,要么完全无效。事务管理是面向RDBMS的企业应用程序的重要组成部分,用于确保数据完整性和一致性。事务的概念可以用以下四个关键属性来描述,称为ACID

  • 原子性 - 事务应被视为单个操作单元,这意味着要么整个操作序列成功,要么失败。

  • 一致性 - 这表示数据库参照完整性、表中唯一主键等的一致性。

  • 隔离性 - 可能会有许多事务同时处理相同的数据集。每个事务都应与其他事务隔离,以防止数据损坏。

  • 持久性 - 一旦事务完成,此事务的结果必须永久保存,并且由于系统故障而不能从数据库中删除。

真实的RDBMS数据库系统将保证每个事务的这四个属性。使用SQL向数据库发出事务的简单视图如下:

  • 使用begin transaction命令开始事务。

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

  • 如果所有操作都成功,则执行commit,否则rollback所有操作。

Spring框架在不同的底层事务管理API之上提供了一个抽象层。Spring的事务支持旨在通过向POJO添加事务功能来提供EJB事务的替代方案。Spring支持程序化和声明式事务管理。EJB需要应用程序服务器,但是Spring事务管理无需应用程序服务器即可实现。

本地事务与全局事务

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

本地事务管理在应用程序组件和资源位于单个站点且事务管理仅涉及在单个机器上运行的本地数据管理器的情况下非常有用。本地事务更容易实现。

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

程序化与声明式

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

  • 程序化事务管理 - 这意味着您必须借助编程来管理事务。这为您提供了极大的灵活性,但难以维护。

  • 声明式事务管理 - 这意味着您将事务管理与业务代码分开。您只需使用注解或基于XML的配置来管理事务。

尽管声明式事务管理不如程序化事务管理灵活,后者允许您通过代码控制事务,但声明式事务管理更可取。但是,作为一种横切关注点,声明式事务管理可以通过AOP方法进行模块化。Spring通过Spring AOP框架支持声明式事务管理。

Spring事务抽象

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;
}

序号 方法及描述
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();
}

序号 方法及描述
1

int getPropagationBehavior()

此方法返回传播行为。Spring提供所有从EJB CMT熟悉的事务传播选项。

2

int getIsolationLevel()

此方法返回此事务与其他事务工作的隔离程度。

3

String getName()

此方法返回此事务的名称。

4

int getTimeout()

此方法返回事务必须完成的时间(秒)。

5

boolean isReadOnly()

此方法返回事务是否为只读。

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

序号 隔离级别及描述
1

TransactionDefinition.ISOLATION_DEFAULT

这是默认的隔离级别。

2

TransactionDefinition.ISOLATION_READ_COMMITTED

指示脏读被阻止;不可重复读和幻读可能会发生。

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

指示脏读、不可重复读和幻读都可能发生。

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

指示脏读和不可重复读被阻止;幻读可能会发生。

5

TransactionDefinition.ISOLATION_SERIALIZABLE

指示脏读、不可重复读和幻读都被阻止。

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

序号 传播类型及描述
1

TransactionDefinition.PROPAGATION_MANDATORY

支持当前事务;如果没有当前事务,则抛出异常。

2

TransactionDefinition.PROPAGATION_NESTED

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

3

TransactionDefinition.PROPAGATION_NEVER

不支持当前事务;如果存在当前事务,则抛出异常。

4

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

不支持当前事务;而是始终非事务性地执行。

5

TransactionDefinition.PROPAGATION_REQUIRED

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

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW

创建一个新事务,如果存在当前事务则挂起。

7

TransactionDefinition.PROPAGATION_SUPPORTS

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

8

TransactionDefinition.TIMEOUT_DEFAULT

使用底层事务系统的默认超时,或者如果不支持超时则为无。

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

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

序号 方法及描述
1

boolean hasSavepoint()

此方法返回此事务是否内部包含保存点,即是否已基于保存点创建为嵌套事务。

2

boolean isCompleted()

此方法返回此事务是否已完成,即它是否已提交或回滚。

3

boolean isNewTransaction()

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

4

boolean isRollbackOnly()

此方法返回事务是否已被标记为仅回滚。

5

void setRollbackOnly()

此方法将事务设置为仅回滚。

广告