目录
什么是事务?
局部事务和全局事务
可编程事务管理和Java注解型事务管理
Spring抽象事务层
数据库事务就是将数据库的一系列操作作为一个工作单元。这一系列的操作要么一起生效要么就全都不起作用。事务管理是数据库中非常重要的组成部分,它能确保数据的一致性和完整性。
事务具有如下几个特点:
一个关系型数据库的事务管理必须满足上边的四个特性,拿一个简单的SQL例子来展示一下,
用 begin transaction 来开始事务;
用SQL执行deleted, update or insert操作;
如果所有的这些操作执行成功,那就执行commit 否则的话 rollback所有的操作。
Spring或者Spring Boot在各种各样的事务Transaction管理API上封装了一层抽象层。Spring Boot 提供了两种事务管理方式:可编程型和Java注解型事务管理, 在下一系列来分别阐述其使用详解。
局部事务就是指单一资源的事务管理,比方说一个JDBC连接。而全局事务扩展到多个事务资源,比如分布式事务。
如果应用程序和数据库部署在单一位置上(application,resource可不在同一机器上),事务也仅仅是在一个机器上进行的数据管理,在这种情况下,局部事务是非常有效的。
而在分布式环境里, 所有的资源会部署到多个系统里,在这种情况下,事务管理要在局部层和全局层都要生效。一个分布式事务或者全局事务运行在多个系统里,这就要求全局事务管理和局部的数据管理必须协调一致地运行下去。
Spring和Spring Boot 支持两种类型的事务管理:
关于这一节内容,会在Transaction理解(二)和(三)里分别阐述。
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;
}
Method | Description |
---|---|
getTransaction | Return a currently active transaction or create a new one, according to the specified propagation behavior. |
commit | Commit the given transaction, with regard to its status. If the transaction has been marked rollback-only programmatically, perform a rollback. |
rollback | Perform a rollback of the given transaction. |
另外一个核心组成部分是TransactionDefinition接口
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;
int PROPAGATION_NESTED = 6;
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int TIMEOUT_DEFAULT = -1;
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
String getName();
}
Method | Description |
---|---|
getPropagationBehavior | Return the propagation behavior. Must return one of the |
getIsolationLevel | Return the isolation level. |
getTimeout | Return the transaction timeout. |
isReadOnly | Return whether to optimize as a read-only transaction. |
getName | Return the name of this transaction. Can be |
接下来列举一下如何事务的隔离性
Isolation | Description |
---|---|
ISOLATION_DEFAULT | Use the default isolation level of the underlying datastore. All other levels correspond to the JDBC isolation levels. |
ISOLATION_READ_UNCOMMITTED | Indicates that dirty reads, non-repeatable reads and phantom reads can occur |
ISOLATION_READ_COMMITTED | Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur. |
ISOLATION_REPEATABLE_READ | Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur. |
ISOLATION_SERIALIZABLE | Indicates that dirty reads, non-repeatable reads and phantom reads are prevented. |
接下来还有事务之间的关系
Propagation | Description |
---|---|
PROPAGATION_REQUIRED | Support a current transaction; create a new one if none exists. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_SUPPORTS | Support a current transaction; execute non-transactionally if none exists. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_MANDATORY | Support a current transaction; throw an exception if no current transaction exists. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_REQUIRES_NEW | Create a new transaction, suspending the current transaction if one exists. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_NOT_SUPPORTED | Do not support a current transaction; rather always execute non-transactionally. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_NEVER | Do not support a current transaction; throw an exception if a current transaction exists. Analogous to the EJB transaction attribute of the same name. |
PROPAGATION_NESTED | Execute within a nested transaction if a current transaction exists, behave like |
TIMEOUT_DEFAULT | Use the default timeout of the underlying transaction system, or none if timeouts are not supported. |
TransactionStatus 接口提供了一系列管理事务和获取事务状态的方式方法。
public interface TransactionStatus extends SavepointManager, Flushable {
/**
* Return whether the present transaction is new (else participating
* in an existing transaction, or potentially not running in an
* actual transaction in the first place).
*/
boolean isNewTransaction();
/**
* Return whether this transaction internally carries a savepoint,
* that is, has been created as nested transaction based on a savepoint.
* This method is mainly here for diagnostic purposes, alongside
* {@link #isNewTransaction()}. For programmatic handling of custom
* savepoints, use SavepointManager's operations.
* @see #isNewTransaction()
* @see #createSavepoint
* @see #rollbackToSavepoint(Object)
* @see #releaseSavepoint(Object)
*/
boolean hasSavepoint();
/**
* Set the transaction rollback-only. This instructs the transaction manager
* that the only possible outcome of the transaction may be a rollback, as
* alternative to throwing an exception which would in turn trigger a rollback.
*
This is mainly intended for transactions managed by
* {@link org.springframework.transaction.support.TransactionTemplate} or
* {@link org.springframework.transaction.interceptor.TransactionInterceptor},
* where the actual commit/rollback decision is made by the container.
* @see org.springframework.transaction.support.TransactionCallback#doInTransaction
* @see org.springframework.transaction.interceptor.TransactionAttribute#rollbackOn
*/
void setRollbackOnly();
/**
* Return whether the transaction has been marked as rollback-only
* (either by the application or by the transaction infrastructure).
*/
boolean isRollbackOnly();
/**
* Flush the underlying session to the datastore, if applicable:
* for example, all affected Hibernate/JPA sessions.
*
This is effectively just a hint and may be a no-op if the underlying
* transaction manager does not have a flush concept. A flush signal may
* get applied to the primary resource or to transaction synchronizations,
* depending on the underlying resource.
*/
@Override
void flush();
/**
* Return whether this transaction is completed, that is,
* whether it has already been committed or rolled back.
* @see PlatformTransactionManager#commit
* @see PlatformTransactionManager#rollback
*/
boolean isCompleted();
}