Spring 事务管理



  • 事务

    数据库事务是被视为单个工作单元的一系列操作。这些动作要么完全完成要么完全不起作用。事务管理是面向RDBMS的企业应用程序的重要组成部分,可确保数据完整性和一致性。事务的概念可以与描述为以下四个关键属性来描述ACID
    • 原子性 - 事务应被视为单个操作单元,这意味着整个操作序列要么成功要么失败。
    • 一致性 - 这表示数据库参照完整性,表中唯一主键的一致性等。
    • 隔离性 - 可能有许多事务处理同时使用相同的数据集。每个事务都应与其他事务隔离,以防止数据损坏。
    • 持久性 - 事务完成后,该事务的结果必须永久保存,并且由于系统故障而无法从数据库中删除。
    一个真正的RDBMS数据库系统将保证每个事务的所有四个属性。使用SQL发布到数据库的事务的简单步骤如下
    • 使用begin transaction命令开始事务。
    • 使用SQL查询执行各种删除,更新或插入操作。
    • 如果所有操作均成功,则执行提交,否则回滚所有操作。
    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;
    }
    
    方法与说明:
    • TransactionStatus getTransaction(TransactionDefinition definition) - 此方法根据指定的传播行为返回当前活动的事务或创建一个新的事务。
    • void commit(TransactionStatus status) - 此方法根据其状态落实给定的事务。
    • void rollback(TransactionStatus status) - 此方法执行给定事务的回滚。
    TransactionDefinition的是Spring中的事务支持的核心接口,并将其定义如下
    public interface TransactionDefinition {
       int getPropagationBehavior();
       int getIsolationLevel();
       String getName();
       int getTimeout();
       boolean isReadOnly();
    }
    
    方法与说明:
    • int getPropagationBehavior() - 此方法返回传播行为。Spring提供了EJB CMT熟悉的所有事务传播选项。
    • int getIsolationLevel()) - 此方法返回此事务与其他事务的工作隔离的程度。
    • String getName()) - 此方法返回此事务的名称。
    • int getTimeout()) - 此方法以秒为单位返回必须完成事务的时间。
    • boolean isReadOnly()) - 此方法返回事务是否为只读。
    以下是隔离级别的可能值
    • TransactionDefinition.ISOLATION_DEFAULT - 这是默认的隔离级别。
    • TransactionDefinition.ISOLATION_READ_COMMITTED - 指示防止脏读;可能会发生不可重复的读取和幻像读取。
    • TransactionDefinition.ISOLATION_READ_UNCOMMITTED - 表示可能发生脏读,不可重复读和幻像读。
    • TransactionDefinition.ISOLATION_REPEATABLE_READ - 指示防止脏读和不可重复读;幻像读取可能发生。
    • TransactionDefinition.ISOLATION_SERIALIZABLE - 指示防止脏读,不可重复读和幻像读。
    以下是传播类型的可能值
    • TransactionDefinition.PROPAGATION_MANDATORY - 支持当前事务;如果当前事务不存在,则引发异常。
    • TransactionDefinition.PROPAGATION_NESTED - 如果当前事务存在,则在嵌套事务中执行。
    • TransactionDefinition.PROPAGATION_NEVER - 不支持当前事务;如果当前事务存在,则引发异常。
    • TransactionDefinition.PROPAGATION_NOT_SUPPORTED - 不支持当前事务;而是始终以非事务方式执行。
    • TransactionDefinition.PROPAGATION_REQUIRED - 支持当前事务;如果不存在,则创建一个新的。
    • TransactionDefinition.PROPAGATION_REQUIRES_NEW - 创建一个新事务,如果存在则暂停当前事务。
    • TransactionDefinition.PROPAGATION_SUPPORTS - 支持当前事务;如果不存在,则以非事务方式执行。
    • TransactionDefinition.TIMEOUT_DEFAULT - 使用基础事务系统的默认超时;如果不支持超时,则不使用默认超时。
    TransactionStatus接口为处理事务的代码来控制事务执行和查询事务状态的简单方法。
    public interface TransactionStatus extends SavepointManager {
       boolean isNewTransaction();
       boolean hasSavepoint();
       void setRollbackOnly();
       boolean isRollbackOnly();
       boolean isCompleted();
    }
    
    方法说明:
    • boolean hasSavepoint() - 此方法返回此事务是否在内部携带保存点,即是否已基于保存点将其创建为嵌套事务。
    • boolean isCompleted() - 此方法返回此事务是否完成,即它是否已经提交或回滚。
    • boolean isNewTransaction() - 如果当前事务是新的,则此方法返回true。
    • boolean isRollbackOnly() - 此方法返回事务是否已标记为仅回滚。
    • void setRollbackOnly()) - 此方法将事务设置为仅回滚。