TransactionDefinition
是 Spring 框架中定义事务属性的接口。它提供了一组方法,用于配置事务的行为,如隔离级别、传播行为、超时时间等。通过 TransactionDefinition
,开发者可以精细地控制事务的各个方面,确保事务的正确性和性能。下面详细介绍 TransactionDefinition
接口及其主要方法和属性。
源码
package org.springframework.transaction;
/**
* Interface that specifies a transaction definition.
* Used for programmatic transaction management.
*
* @author Juergen Hoeller
* @since 19.03.2003
* @see PlatformTransactionManager
*/
public interface TransactionDefinition {
// 支持当前事务,若当前没有事务就创建一个新的事物
int PROPAGATION_REQUIRED = 0;
// 如果当前存在事务,则加入该事物;如果当前没有事务,则以非事物的方式继续运行
int PROPAGATION_SUPPORTS = 1;
// 如果当前存在事务,则加入该事物,如果当前没有事务,则抛出异常
int PROPAGATION_MANDATORY = 2;
// 创建一个新的事物,如果当前存在事务,则把当前事务挂起
int PROPAGATION_REQUIRES_NEW = 3;
// 以非事物方式运行,如果当前存在事务,则把当前事务挂起
int PROPAGATION_NOT_SUPPORTED = 4;
// 以非事物方式运行,如果当前存在事务,则抛出异常
int PROPAGATION_NEVER = 5;
// 如果当前正有一个事物在运行中,则该方法运行在一个嵌套的事物中,被嵌套的事物可以独立于封装的事物进行提交或者回滚
// 如果封装的事物不存在,后续事物行为就跟PROPAGATION_REQUIRES_NEW 一样
int PROPAGATION_NESTED = 6;
// 使用后端数据库默认的隔离界别
int ISOLATION_DEFAULT = -1;
// 最低的隔离界别
int ISOLATION_READ_UNCOMMITTED = 1;
// 组织脏读,但是可能会产生幻读,或不可重复读的问题
int ISOLATION_READ_COMMITTED = 2;
// 可以组织脏读或不可重复读,但可能会发生幻读
int ISOLATION_REPEATABLE_READ = 4;
// 可以防止脏读、不可重复读以及幻读
int ISOLATION_SERIALIZABLE = 8;
// 使用默认的超时时间
int TIMEOUT_DEFAULT = -1;
/**
* Name of this transaction, if any.
* Primarily for display purposes.
*/
// 返回事务的名称
// 主要用于日志记录和调试。事务名称可以帮助开发者更好地理解事务的上下文
String getName();
/**
* Return the propagation behavior of this transaction.
* See the constants in this interface for details.
*/
// 返回事务的传播行为
// 决定当前事务方法被调用时,事务应该如何处理。
int getPropagationBehavior();
/**
* Return the isolation level of this transaction.
* See the constants in this interface for details.
*/
// 返回事务的隔离级别
// 决定事务在并发执行时的行为。
int getIsolationLevel();
/**
* Return the timeout of this transaction, in seconds.
* If -1, the default timeout of the underlying transaction system will be used.
*/
// 返回事务的超时时间(以秒为单位)
// 如果事务在指定的时间内没有完成,将会被回滚。如果设置为 -1,表示事务没有超时限制。
int getTimeout();
/**
* Return whether this transaction is read-only.
* <p>This just serves as a hint for the actual transaction subsystem; it will <i>not</i>
* necessarily cause failure of write access attempts. A transaction manager which cannot
* interpret the read-only hint will <i>not</i> throw an exception when asked for a read-only
* transaction - rather, it will ignore the hint.
*/
// 返回事务是否为只读事务
// 只读事务可以提高性能,因为数据库可以对其进行优化。只读事务不允许修改数据。
boolean isReadOnly();
// 返回默认的TransactionDefainition
static TransactionDefinition withDefaults() {
return StaticTransactionDefinition.INSTANCE;
}
}
实现类
DefaultTransactionDefinition
-
DefaultTransactionDefinition
是TransactionDefinition
接口的一个默认实现类。它提供了设置和获取事务属性的方法,是大多数情况下配置事务属性的首选类。
RuleBasedTransactionAttribute
-
RuleBasedTransactionAttribute
是TransactionDefinition
接口的一个实现类,用于基于规则的事务属性配置。它允许根据方法的返回值或异常类型来决定事务的行为。
TransactionAttributeSourceAdvisor
- 虽然
TransactionAttributeSourceAdvisor
不直接实现TransactionDefinition
接口,但它使用TransactionDefinition
来配置事务属性。这个类通常用于 AOP 切面,管理事务的切点和通知。
补充
脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)是数据库事务中的三种隔离级别问题,它们描述了在并发环境下,事务可能遇到的数据一致性问题。这些问题通常出现在数据库管理系统(DBMS)中,当多个事务同时访问和修改数据时。下面是对这三种问题的解释:
- 脏读(Dirty Read): 脏读是指在一个事务中读取到了另一个事务未提交的数据。如果第二个事务回滚,那么第一个事务读取的数据实际上是无效的,因为它是基于一个最终会被撤销的更改。脏读会导致数据不一致的问题,因为事务可能会基于错误的数据做出决策。
- 不可重复读(Non-repeatable Read): 不可重复读是指在一个事务内,多次读取同一数据集合,但是每次读取的结果都可能不同。这通常是因为其他事务在这个事务两次读取之间修改了数据。例如,一个事务可能首先读取了一个数据项,然后另一个事务更新了这个数据项,导致第一个事务再次读取时得到不同的结果。这会导致数据不一致,因为事务的读取操作依赖于数据的特定状态。
- 幻读(Phantom Read): 幻读是指在一个事务中,两次执行相同的查询,由于其他事务的插入或删除操作,返回的记录数不同。例如,一个事务可能首先查询了某个范围内的所有记录,然后另一个事务在这个范围内插入了新的记录,导致第一个事务再次查询时发现记录数增加了。幻读通常与范围查询相关,因为它涉及到行的集合,而不仅仅是单个行。
为了解决这些问题,数据库提供了不同的隔离级别:
- 读未提交(Read Uncommitted):这是最低的隔离级别,允许脏读、不可重复读和幻读。
- 读已提交(Read Committed):这个隔离级别防止了脏读,但仍然允许不可重复读和幻读。
- 可重复读(Repeatable Read):这个隔离级别防止了脏读和不可重复读,但仍然允许幻读(在某些数据库系统中,如MySQL的InnoDB存储引擎,通过间隙锁防止幻读)。
- 串行化(Serializable):这是最高的隔离级别,它通过完全锁定涉及的数据来防止脏读、不可重复读和幻读,但这会牺牲并发性能。