Spring事务抽象的是事务管理和事务策略。而实现则由各种资源方实现的。我们最常用的数据库实现:DataSourceTransactionManager

尝试阅读一下spring 的实现代码,由3个核心类:

1,PlatformTransactionManager

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException;

事务管理的抽象,一个获取事务状态,一个提交事务,一个回滚事务。

2,TransactionStatus

public interface TransactionStatus extends SavepointManager, Flushable {

   boolean isNewTransaction();

   boolean hasSavepoint();

   void setRollbackOnly();

   boolean isRollbackOnly();

   void flush();

   boolean isCompleted();

}

事务状态的抽象

3,DefaultTransactionDefinition

public interface TransactionDefinition {

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();

    boolean isReadOnly();

    String getName();

}

事务策略抽象,1,事务传播行为,2,事务隔离级别,3,超时时间,4,只读属性

编程的方法实现事务管理使用简单代码:

transactionTemplate.execute(new TransactionCallback<String>() {
@Override
public String doInTransaction(TransactionStatus status) {
updatePayPrice(orderData, offer);
return null;
}
});

类似下面的配置:

<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate"
p:transactionManager-ref="txManager" scope="prototype" />

TransactionTemplate继承了DefaultTransactionDefinition也就是TransactionDefinition默认实现,afterPropertiesSet方法检查transactionManager,

核心方法execute,其中四步:0.获取一个事务状态,1,执行业务逻辑  2,出现异常,3,没有异常事务提交
public class TransactionTemplate extends DefaultTransactionDefinition
implements TransactionOperations, InitializingBean { /** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass()); private PlatformTransactionManager transactionManager;
public TransactionTemplate() {
}
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
super(transactionDefinition);
this.transactionManager = transactionManager;
} public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
} /**
* Return the transaction management strategy to be used.
*/
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
} @Override
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
} @Override
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
// 0.获取一个事务状态
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
//1.执行业务逻辑
result = action.doInTransaction(status);
}
// 2.异常则回退
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
catch (Exception ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
// 3.没有异常事务提交
this.transactionManager.commit(status);
return result;
}
} private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
logger.debug("Initiating transaction rollback on application exception", ex);
try {
this.transactionManager.rollback(status);
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by rollback error", ex);
throw err;
}
} }
0,获取一个事务状态
this.transactionManager.getTransaction(this);
这里的transactionManager就是前面使用代码的配置中txManager,就是DataSourceTransactionManager,模版类AbstractPlatformTransactionManager。而传参this就是DefaultTransactionDefinition。
下面是AbstractPlatformTransactionManager里的模版方法:
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
// 进来就先获取事务
Object transaction = doGetTransaction(); // Cache debug flag to avoid repeated checks.
// 这里为打日志判断日志级别做的优化,这个在http://www.cnblogs.com/killbug/p/6721047.html 最后有解释。
boolean debugEnabled = logger.isDebugEnabled(); if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
} if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
} // Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
} // No existing transaction found -> check propagation behavior to find out how to proceed.
// 配置了PROPAGATION_MANDATORY就不能调用这个方法的,这个方法是开始获取事务的地方
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);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
// 新建事务
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}
catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
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);
}
}

1,回滚代码:

private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
logger.debug("Initiating transaction rollback on application exception", ex);
try {
this.transactionManager.rollback(status);
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by rollback error", ex);
throw err;
}
}

transactionManager.rollback

public final void rollback(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
} DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus);
}
//模版方法 子类实现自己的会滚操作
private void processRollback(DefaultTransactionStatus status) {
try {
try {
triggerBeforeCompletion(status);
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);
}
else if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
doSetRollbackOnly(status);
}
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
}
catch (RuntimeException ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
catch (Error err) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw err;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}
finally {
cleanupAfterCompletion(status);
}
}

事务提交:

// 模版
public final void commit(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
} DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus);
return;
}
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus);
// Throw UnexpectedRollbackException only at outermost transaction boundary
// or if explicitly asked to.
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
return;
} processCommit(defStatus);
}

AbstractPlatformTransactionManager做为模版类,代码清晰。

我们发现在上面的execute,异常会退时是不没有任何区分什么异常会滚,什么异常不会滚,都是走rollbackOnException。其实我们只要在业务方法中把异常吃掉即可,另外对于回滚后异常抛出,在最外层再把异常做处理。

本篇没有真正深入了解原理实现,写在这里是为了开个头。

spring事务管理-Spring 源码系列(6)的更多相关文章

  1. 【spring源码学习】spring的事务管理的源码解析

    [一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transact ...

  2. spring事务传播实现源码分析

    转载. https://blog.csdn.net/qpfjalzm123/article/details/83717367 本文只是对spring事务传播实现的流程进行简单的分析,如有不对之处请指出 ...

  3. Mybatis整合Spring实现事务管理的源码分析

    一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...

  4. spring事务管理学习

    spring事务管理学习 spring的事务管理和mysql自己的事务之间的区别 参考很好介绍事务异常回滚的文章 MyBatis+Spring 事务管理 spring中的事务回滚例子 这篇文章讲解了@ ...

  5. spring事务管理实现原理-源码-传播属性

    转载请标识 https://me.csdn.net/wanghaitao4j https://blog.csdn.net/wanghaitao4j/article/details/83625260 本 ...

  6. SSM(spring mvc+spring+mybatis)学习路径——1-2、spring事务管理

    目录 1-2 Spring事务管理 概念介绍 事务回顾 事务的API介绍 Spring 事务管理 转账案例 编程式事务管理 声明式事务管理 使用XML配置声明式事务 基于tx/aop 使用注解配置声明 ...

  7. 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)

    Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...

  8. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

  9. Spring源码系列(三)--spring-aop的基础组件、架构和使用

    简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...

  10. Spring源码系列(四)--spring-aop是如何设计的

    简介 spring-aop 用于生成动态代理类(底层是使用 JDK 动态代理或 cglib 来生成代理类),搭配 spring-bean 一起使用,可以使 AOP 更加解耦.方便.在实际项目中,spr ...

随机推荐

  1. 使用virustotal VT 查询情报——感觉远远没有微步、思科好用,10万条数据查出来5万条都有postives >0的记录,尼玛!!!

    1399 git clone https://github.com/VirusTotal/c-vtapi.git 1400 cd c-vtapi/ 1402 sudo apt-get install ...

  2. Qt与JS(三)

    Qt不错的学习网址: http://www.cnblogs.com/findumars/p/5529526.html ----------------------------------------- ...

  3. python-flask基础

    get请求: 使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这时候使用get请求. 传参:get请求传参是放在url中,并且是通过’?’的形式来指定key和value的. post ...

  4. sigmoid belief network boltszmann machine

    because of explaining away, the hidden weights in sigmoid belief network is no longer independent

  5. java 单例模式5种写法

    学习整理 饱汉模式(懒汉模式) // 饱汉 // UnThreadSafe public class Singleton1 { private static Singleton1 singleton ...

  6. shell脚本分析二

    Shell 基本运算符Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符原生bash不支持简单的数学运算,但是可以通过其他命令来实 ...

  7. Blazor

    https://docs.microsoft.com/zh-cn/windows/uwp/get-started/construct-form-learning-track https://docs. ...

  8. day26-python操作redis二

    字符串的操作 #redis中的string 在内存中都是按照一个key对应一个valus来存储的 import redis pool = redis.ConnectionPool(host=" ...

  9. Pamulinawen--IPA--菲律宾伊洛卡诺语

    这是一首菲律宾的民谣(不是他加禄语/Tagalog, 而是伊洛卡诺语/Ilokano), 我们国家的著名歌手朱明瑛也翻唱过, 歌曲中文名为<<田野之歌>>.

  10. 团队项目开发特点以及NABCD分析总结

    (注:此博客来源于韩晓凡,我们是一个团队) 团队项目的特点:开发的这款软件是从我们的日常生活中得到的启发,现在正是大学阶段,刚刚开始管理自己每个月的生活费,并且在大学中每个月的生活费会有很多去处,然而 ...