spring事务管理-Spring 源码系列(6)
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,
- 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;
- }
- }
- }
- 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)的更多相关文章
- 【spring源码学习】spring的事务管理的源码解析
[一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transact ...
- spring事务传播实现源码分析
转载. https://blog.csdn.net/qpfjalzm123/article/details/83717367 本文只是对spring事务传播实现的流程进行简单的分析,如有不对之处请指出 ...
- Mybatis整合Spring实现事务管理的源码分析
一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...
- spring事务管理学习
spring事务管理学习 spring的事务管理和mysql自己的事务之间的区别 参考很好介绍事务异常回滚的文章 MyBatis+Spring 事务管理 spring中的事务回滚例子 这篇文章讲解了@ ...
- spring事务管理实现原理-源码-传播属性
转载请标识 https://me.csdn.net/wanghaitao4j https://blog.csdn.net/wanghaitao4j/article/details/83625260 本 ...
- SSM(spring mvc+spring+mybatis)学习路径——1-2、spring事务管理
目录 1-2 Spring事务管理 概念介绍 事务回顾 事务的API介绍 Spring 事务管理 转账案例 编程式事务管理 声明式事务管理 使用XML配置声明式事务 基于tx/aop 使用注解配置声明 ...
- 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)
Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...
- 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)
一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...
- Spring源码系列(三)--spring-aop的基础组件、架构和使用
简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...
- Spring源码系列(四)--spring-aop是如何设计的
简介 spring-aop 用于生成动态代理类(底层是使用 JDK 动态代理或 cglib 来生成代理类),搭配 spring-bean 一起使用,可以使 AOP 更加解耦.方便.在实际项目中,spr ...
随机推荐
- 部署java项目到服务器
1.首先判断服务器是什么系统 linux,windows 2.如果是linux使用SSH进行链接 3.如果是windows使用远程桌面进行链接 1.windows+R->mstsc进行远程桌面的 ...
- Linux查看某个命令属于哪个包
有时修我们需要某个命令但其没有安装,提供该命令的包名也与命令名相差很大直接查找命令名找不到包,如rexec. 此时我们就非常需要这样一个工具:可以根据最终的命令查找提供该命令的软件包. 类型 命令 说 ...
- 基于spring的PropertySource类实现配置的动态替换
public class ConfigPropertySource extends PropertySource<Properties> implements PriorityOrdere ...
- possible error
1● regedit 2● path [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Windows Error Reporting] 3● 步 ...
- ubuntu 挂载虚拟机vdi文件
sudo apt-get install nbd-server nbd-client qemu-kvm # rmmod nbd # modprobe nbd max_part=8 # qemu- ...
- linux下sed命令详解
sed:Stream Editor文本流编辑,sed是一个“非交互式的”面向字符流的编辑器.能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上 ...
- CString 转换为 wchar_t *
1.将CString转换为const char* CString str = _T("231222"); std::string strDp = CStringA(str); / ...
- linux command mktemp
Linux command mktemp [Purpose] Learning linux command mktemp to create a temporary file or di ...
- Linux系统从零到高手的进阶心得
初次了解到Linux系统还是在我初中的时候,那时候正是在一个中二年龄,喜欢看小说,对于小说中出现的明显的非现实场景感到十分钦佩.羡慕,并常常幻想自己也有小说主人公那样的本领.那正是在这样一个充满幻想的 ...
- FFT模板(无讲解)
#include<bits/stdc++.h> using namespace std; ; const double pi=3.1415926535898; ],len; struct ...