Transaction Management
数据库事务是一系列被视为单个工作单元的操作。 这些操作应该完全完成或根本不起作用。 事务管理是面向RDBMS的企业应用程序的重要组成部分,可确保数据的完整性和一致性。 交易的概念可以用以下描述为ACID四个关键属性来描述 -
Atomicity - 事务应被视为单个操作单元,这意味着整个操作序列成功或不成功。
Consistency - 这表示数据库的参照完整性,表中的唯一主键等的一致性。
Isolation - 可能会有许多事务处理同时使用相同的数据集。 每个事务都应与其他事务隔离,以防止数据损坏。
Durability - 事务完成后,此事务的结果必须是永久性的,并且由于系统故障而无法从数据库中删除。
真正的RDBMS数据库系统将保证每个事务的所有四个属性。 使用SQL向数据库发出的事务的简单视图如下 -
使用begin transaction命令begin transaction 。
使用SQL查询执行各种删除,更新或插入操作。
如果所有操作都成功,则执行commit否则rollback所有操作。
Spring框架在不同的底层事务管理API之上提供了一个抽象层。 Spring的事务支持旨在通过向POJO添加事务功能来提供EJB事务的替代方法。 Spring支持编程和声明式事务管理。 EJB需要应用程序服务器,但可以在不需要应用程序服务器的情况下实现Spring事务管理。
本地与全球交易
本地事务特定于单个事务资源(如JDBC连接),而全局事务可以跨越多个事务资源,如分布式系统中的事务。
本地事务管理在应用程序组件和资源位于单个站点的集中式计算环境中非常有用,而事务管理仅涉及在单个机器上运行的本地数据管理器。 本地交易更容易实施。
在分布式计算环境中需要全局事务管理,其中所有资源都分布在多个系统中。 在这种情况下,交易管理需要在本地和全球层面进行。 跨多个系统执行分布式或全局事务,并且其执行需要全局事务管理系统与所有涉及系统的所有本地数据管理器之间的协调。
程序化与声明性
Spring支持两种类型的事务管理 -
Programmatic transaction management - 这意味着您必须在编程的帮助下管理事务。 这为您提供了极大的灵活性,但很难维护。
Declarative transaction management - 这意味着您将事务管理与业务代码分开。 您只能使用注释或基于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;
}
Sr.No | 方法和描述 |
---|---|
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 | 方法和描述 |
---|---|
1 | int getPropagationBehavior() 此方法返回传播行为。 Spring提供了EJB CMT熟悉的所有事务传播选项。 |
2 | int getIsolationLevel() 此方法返回此事务与其他事务的工作隔离的程度。 |
3 | String getName() 此方法返回此事务的名称。 |
4 | int getTimeout() 此方法返回事务必须完成的时间(以秒为单位)。 |
5 | boolean isReadOnly() 此方法返回事务是否为只读。 |
以下是隔离级别的可能值 -
Sr.No | 隔离和描述 |
---|---|
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. | 传播与描述 |
---|---|
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 使用基础事务系统的默认超时,如果不支持超时,则使用none。 |
TransactionStatus接口为事务代码提供了一种控制事务执行和查询事务状态的简单方法。
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
Sr.No. | 方法和描述 |
---|---|
1 | boolean hasSavepoint() 此方法返回此事务是否内部携带保存点,即是否已基于保存点创建为嵌套事务。 |
2 | boolean isCompleted() 此方法返回此事务是否已完成,即是否已提交或回滚。 |
3 | boolean isNewTransaction() 如果当前事务是新事务,则此方法返回true。 |
4 | boolean isRollbackOnly() 此方法返回事务是否已标记为仅回滚。 |
5 | void setRollbackOnly() 此方法将事务设置为仅回滚。 |