一、官网地址:
https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/data-access.html#
Transaction
二、实现方式:
2.1 通过xml配置:
2.1.1配置transanctionManager, 属性 dataSource
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2.1.2 基于Aop 配置事务增强 <tx> 标签 是transaction 提供的标签,在这里可以配置指定某些方法定义事务的传播行为,隔离级别。
image.png
2.2 通过注解配置:
开启spring 注解事务的注解:@EnableTransactionManagement
在要加事务管理的类或方法上加@Transactional,如果需要对事务的其他属性进行配置时,即在注解上面配置相关属性即可。
image.png
2.3 编程式事务:
1 定义TransactionDefinition 作为transactionManager的入参条件来获取TransactionStatus,其中DefaultTransactionDefinition 定义了事务的属性。
TransactionDefinition definition = new DefaultTransactionDefinition();
TransactionStatus status = txManager.getTransaction(definition);
try{
//业务
txManager.commit(status);
}catch(Exception e){
//出现异常手动回滚
txManager.rollback(status );
}
还有一种直接获取TransactionStatus 并将他设置成rollbackOnly
public void resolvePosition() {
try {
// some business logic...
} catch (NoProductInStockException ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
2 spring 还提供了事务模版用来管理事务:
TransactionTemplate 执行 execute();方法来完成相关事务操作。
可以自己在此基础上造个轮子:
package com.chen.springboot.bootlearn.template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@Component
public class SpringTransaction {
@Autowired
private TransactionTemplate transactionTemplate; // TransactionTemplate 作为spring bean维护
//提供一个模版方法 子类重写具体业务
public Object execute(TransactionTemplates templates) {
Object result = new Object();
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
templates.lock();
} finally {
System.out.println("Lock");
}
try {
templates.check();
} finally {
System.out.println("Check");
}
try {
templates.process();
} finally {
System.out.println("Process");
}
}
});
return result;
}
}
遇到需要调用事务的时候 直接执行 execute()方法即可
@Override
public Object addCount(User user) {
Object object = new Object();
transaction.execute(new TransactionTemplates() {
@Override
public void check() {
}
@Override
public void lock() {
}
@Override
public void process() {
}
});
return object;
}
三 事务API
Spring事务核心的API:
3.1 : PlatformTransactionManager,平台级的事务管理器,它抽象定义了事务管理行为,不同
的事务管理实现实现该接口。我们编程面向该接口。继承关系图如下所示:
image.png
3.1.1 抽象方法也很简单:
image.png
3.2 : TransactionDefinition:事务定义。Spring 事务管理框架将为我们管理事务,但不清楚该
如何替我们管理,我们就通过事务定义来定义我们需要的事务管理信息,把这些信息给事务
管理器,它就知道我们的意图了。
接口 的结构图如下所示:
image.png
继承关系图:
image.png
3.3:TransactionStatus 事务状态,持有事务的状态信息。事务管理代码可通过它获取事务状态、
以及显式地设置回滚(代替异常的方式)。它继承了 SavePoint 接口。在它的实现中会持有事
务的很多对象:如事务对象、被挂起的事务资源等。
从 TransactionManager 中获取事务得到它,提交/回滚事务时要给入它:
类结构图:
image.png
继承关系图:
image.png
四 具体实现流程:
验证:DataSourceTransactionManager
DataSourceTransactionManager 是基于 jdbc connection 的本地事务管理实现。多个方法
调用参与到同一个事务,是通过共用 connection 来完成的。
通过不同的事务传播属性,执行方法时也会有不同。验证不同传播属性对事务的影响:
方法一 required --- 方法二 required
方法一 required --- 方法二 requires_new
方法一 required --- 方法二 nested (当前存在事务 则嵌套在事务内执行,没有事务则新开启一个事务)
具体代码 主要集中在 AbstractPlatformTransactionManager
典型的模板方法的设计模式, 子类调用父类的 getTransaction(),这个方法时不能不能不重写的方法,子类只能重写里面的 doGetTransaction() 封装事务对象,isExistingTransaction():判断是否存在事务,handleExistingTransaction():存在事务的处理流程,doBegin():开启事务。doCommit():提交事务,doRollback():回滚事务。
image.png
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
//获取事务对象 TransactionObject 由子类去实现
Object transaction = doGetTransaction();
if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
}
if (isExistingTransaction(transaction)) {//是否存在事务
//存在事务如何处理
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// 不存在事务检查事务传播行为
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
//封装: DefaultTransactionStatus : 1事务对象 2是否是新事务 3 事务同步器是否开启默认是开着的 4 是否 开启只读控制。 5 挂起的资源
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//开启事务
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// 传播行为 为其他的时候就不做任何处理,也要封装一个 TransactionStatus对象
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
具体执行流程如下图所示:
SptingTransation.png获取事务对象:
@Override
protected Object doGetTransaction() {
// 每来一个事务时都要创建一个事务对象
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
ConnectionHolder conHolder =
//从当前ThreadLocal (TransactionSynchronizationManager) 中获取一个连接 并放到事务对象。
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
TransactionSynchronizationManager 为了保证多线程下事务不出现混乱,通过ThreadLocal 来保证线程的同步.
public abstract class TransactionSynchronizationManager {
private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);
private static final ThreadLocal<Map<Object, Object>> resources =
new NamedThreadLocal<>("Transactional resources");
private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
new NamedThreadLocal<>("Transaction synchronizations");
private static final ThreadLocal<String> currentTransactionName =
new NamedThreadLocal<>("Current transaction name");
private static final ThreadLocal<Boolean> currentTransactionReadOnly =
new NamedThreadLocal<>("Current transaction read-only status");
private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
new NamedThreadLocal<>("Current transaction isolation level");
private static final ThreadLocal<Boolean> actualTransactionActive =
new NamedThreadLocal<>("Actual transaction active");
···················
}
判断是否存在事务:
@Override
protected boolean isExistingTransaction(Object transaction) {
//判断事务对象中是否存在连接持有器,连接持有器中的事务是否被激活
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}
对挂起事务的恢复
protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
throws TransactionException {
if (resourcesHolder != null) {
Object suspendedResources = resourcesHolder.suspendedResources;
if (suspendedResources != null) {
doResume(transaction, suspendedResources);
}
List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
if (suspendedSynchronizations != null) {
TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
doResumeSynchronization(suspendedSynchronizations);
}
}
}
网友评论