一、事务状态:org.springframework.transaction.TransactionStatus

isNewTransaction 是否是新事务

hasSavepoint 是否有保存点

setRollbackOnly 设置回滚

isRollbackOnly 是否回滚

flush 刷新

isCompleted 是否完成

二、传播行为

1.传播行为分类

类别

简称

无事务

已有事务

PROPAGATION_REQUIRED

Required(必须-默认)

创建一个新的事务

使用该事务

PROPAGATION_SUPPORTS

Supports(支持)

以非事务执行

使用该事务

PROPAGATION_MANDATORY

Mandatory(强制)

抛异常

使用该事务

PROPAGATION_REQUIRES_NEW

requires_new(必须新的)

创建一个新的事务

原事务挂起,创建一个新的事务

PROPAGATION_NOT_SUPPORTED

not_supported(不支持)

以非事务执行

原事务挂起,以非事务执行

PROPAGATION_NEVER

Never(从不)

以非事务执行

抛异常

PROPAGATION_NESTED

Nested(嵌套)

创建一个新事务

在嵌套事务内执行

2.传播行为源码分析

(1)获取事务org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(TransactionDefinition definition)

    //---------------------------------------------------------------------
// Implementation of PlatformTransactionManager
//--------------------------------------------------------------------- /**
* This implementation handles propagation behavior. Delegates to
* <code>doGetTransaction</code>, <code>isExistingTransaction</code>
* and <code>doBegin</code>.
* @see #doGetTransaction
* @see #isExistingTransaction
* @see #doBegin
*/
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction(); // Cache debug flag to avoid repeated checks.
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());
}
     // 下面是不存在事务情况下,根据传播行为处理
     // 如果配置的是mandatory强制,抛异常 
// No existing transaction found -> check propagation behavior to find out how to proceed.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
     // 如果是required必须、requires_new必须新的和nested嵌套时,创建一个新的事物
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.
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}

(2)已有事务时处理org.springframework.transaction.support.AbstractPlatformTransactionManager.TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)

    /**
* Create a TransactionStatus for an existing transaction.
*/
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
     // 下面是对已有事务,根据传播行为处理
    
     // 如果配置的是never从不,抛异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
     // 如果配置的是not_support不支持,原事务挂起,以非事务执行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
     // 如果配置的是requires_new,原事务挂起,创建一个新事务执行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
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 beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
catch (Error beginErr) {
resumeAfterBeginException(transaction, suspendedResources, beginErr);
throw beginErr;
}
}
     // 如果配置是nested嵌套,在嵌套事务中执行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
} // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
if (isValidateExistingTransaction()) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

三、 Spring隔离级别:

  (1)、ISOLATION_DEFAULT:使用后端数据库默认的隔离级别

  (2)、ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

  (3)、ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

  (4)、ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

  (5)、ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的

部分参考:https://www.cnblogs.com/ysocean/p/7617620.html

spring事务概念与获取事务时事务传播行为源码分析的更多相关文章

  1. ElasticSearch 启动时加载 Analyzer 源码分析

    ElasticSearch 启动时加载 Analyzer 源码分析 本文介绍 ElasticSearch启动时如何创建.加载Analyzer,主要的参考资料是Lucene中关于Analyzer官方文档 ...

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

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

  3. Spring Boot启动命令参数详解及源码分析

    使用过Spring Boot,我们都知道通过java -jar可以快速启动Spring Boot项目.同时,也可以通过在执行jar -jar时传递参数来进行配置.本文带大家系统的了解一下Spring ...

  4. spring transaction源码分析--事务架构

    1. 引言  事务特性 事务是并发控制的单元,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务将逻辑相关的一组操作绑定在一起,以便服务器 保持数据的完整性.事 ...

  5. Spring事务源码分析专题(一)JdbcTemplate使用及源码分析

    Spring中的数据访问,JdbcTemplate使用及源码分析 前言 本系列文章为事务专栏分析文章,整个事务分析专题将按下面这张图完成 对源码分析前,我希望先介绍一下Spring中数据访问的相关内容 ...

  6. Spring笔记(5) - 声明式事务@EnableTransactionManagement注解源码分析

    一.背景 前面详解了实现Spring事务的两种方式的不同实现:编程式事务和声明式事务,对于配置都使用到了xml配置,今天介绍Spring事务的注解开发,例如下面例子: 配置类:注册数据源.JDBC模板 ...

  7. [心得体会]spring事务源码分析

    spring事务源码分析 1. 事务的初始化注册(从 @EnableTransactionManagement 开始) @Import(TransactionManagementConfigurati ...

  8. Spring系列28:@Transactional事务源码分析

    本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...

  9. spring事务源码分析结合mybatis源码(一)

    最近想提升,苦逼程序猿,想了想还是拿最熟悉,之前也一直想看但没看的spring源码来看吧,正好最近在弄事务这部分的东西,就看了下,同时写下随笔记录下,以备后查. spring tx源码分析 这里只分析 ...

随机推荐

  1. Jenkins-Master-slave架构(八)

    一.增加slave节点 1.1 查看当前节点 系统管理-节点管理  1.2 新建节点  1.3 配置节点信息 可以选择只允许运行绑定到这台机器的job  1.4 保存后,使节点上线即可. 二.配置任务 ...

  2. [数据结构与算法] 字符串匹配 - BF算法

    BF(Brute Force)算法 又称暴力匹配算法,是一种朴素的模式匹配算法 给定主串 S : Bilibili 和子串 T :Bilididi 步骤: 1. 主串 S 第一位开始与子串 T 第一位 ...

  3. SQLAlchemy 应用创建

    1.首先创建app文件夹 同django 创建app 一样 创建文件 在创建的views中写入两个蓝图函数为了操作数据库的增删改查 acc.py from flask import Blueprint ...

  4. python cookie登录DVWA,phpstudy搭建DVWA参考https://www.jianshu.com/p/97d874548300

    import requestsheader={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleW ...

  5. Linux终端执行shell脚本,提示权限不够

    在学习dubbo过程中,上传自己写的脚本,执行的时候提示“权限不够”,从网上了解到是因为没有为脚本赋权限 解决方法是使用chmod命令为shell脚本赋予权限 chmod 777 ./service- ...

  6. 201871010133-赵永军《面向对象程序设计(java)》第七周学习总结

    201871010133-赵永军<面向对象程序设计(java)>第七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...

  7. [LeetCode] 891. Sum of Subsequence Widths 子序列宽度之和

    Given an array of integers A, consider all non-empty subsequences of A. For any sequence S, let the  ...

  8. okhttp 发送get post 请求

    package com.qlwb.business.util; import java.util.Map; import com.alibaba.fastjson.JSON; import okhtt ...

  9. StackExchange.Redis Timeout performing 超时问题

    最近在做的一个项目,用的.net core 2.1,然后缓存用的Redis,缓存相关封装是同事写的,用的驱动是StackExchange.Redis version 2.0.571 ,一直听说这个驱动 ...

  10. SpringBoot第十九篇:邮件服务

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11118340.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   邮件的重要 ...