Spring事務原始碼分析
事務屬性定義介面
TransactionDefinition是事務屬性定義介面,儲存事務定義的各種屬性,如超時時間、隔離級別、傳播屬性等。
public interface TransactionDefinition {
//獲取事務傳播型別
int getPropagationBehavior();
//獲取事務隔離級別
int getIsolationLevel();
//獲取事務超時時間
int getTimeout();
//事務的只讀性
boolean isReadOnly();
//獲取事務名稱
String getName();
}
事務例項介面
TransactionStatus是事務例項介面,表示了當前事務在記憶體中的一個例項,從名字來看儲存了事務的執行狀態資訊。
AbstractTransactionStatus是抽象實現,DefaultTransactionStatus是事務例項的預設實現。
事務管理器
PlatformTransactionManager是Spring事務的核心介面,一般不會直接使用該介面,應用程式可以直接用TransactionTemplate或者AOP進行事務操作。AbstractPlatformTransactionManager是PlatformTransactionManager的抽象類實現。
public interface PlatformTransactionManager {
//根據事務指定的策略獲取啟用的事務或者重新建立一個事務。
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
//提交事務
void commit(TransactionStatus status) throws TransactionException;
//回滾事務
void rollback(TransactionStatus status) throws TransactionException;
}
AbstractPlatformTransactionManager定義事務實現的骨架。
獲取事務
getTransaction(TransactionDefinition definition)主要邏輯是首先獲取當前執行緒的事務:
Object transaction = doGetTransaction();
注意doGetTransaction是個鉤子方法,負責子類方法的回撥,凡是以do開頭的方法都類似,後續不在贅述。
如果當前執行緒已經存在事務,則handleExistingTransaction(definition, transaction, debugEnabled),這個方法根據配置的事務策略處理存在的事務:
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}
如果當前執行緒不存在事務,則開啟新事務:
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;
}
我們選擇DataSourceTransactionManager的doBegin看看,裡面設定事務為手動提交模式,然後啟用當前事務:
// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false); //設定為手動提交
}
txObject.getConnectionHolder().setTransactionActive(true);
事務提交
主要實現方法是processCommit,在事務提交之前還做了其他額外準備操作,然後執行doCommit方法,出錯時不會進行資源清理操作,不做回滾操作,回滾操作由呼叫者發起。
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
boolean globalRollbackOnly = false;
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
globalRollbackOnly = status.isGlobalRollbackOnly();
}
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
doCommit(status);
}
// Throw UnexpectedRollbackException if we have a global rollback-only
// marker but still didn't get a corresponding exception from commit.
if (globalRollbackOnly) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
...
事務回滾
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);
}
事務同步管理器
TransactionSynchronizationManager關鍵實現是依賴ThreadLocal。各種資料庫資源儲存在各自執行緒的副本中,保證執行緒安全,典型的用空間換時間的做法。
private static final ThreadLocal<Map<Object, Object>> resources =
new NamedThreadLocal<Map<Object, Object>>("Transactional resources");
private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations");
private static final ThreadLocal<String> currentTransactionName =
new NamedThreadLocal<String>("Current transaction name");
private static final ThreadLocal<Boolean> currentTransactionReadOnly =
new NamedThreadLocal<Boolean>("Current transaction read-only status");
private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
new NamedThreadLocal<Integer>("Current transaction isolation level");
private static final ThreadLocal<Boolean> actualTransactionActive =
new NamedThreadLocal<Boolean>("Actual transaction active");
相關推薦
Spring事務原始碼分析
事務屬性定義介面 TransactionDefinition是事務屬性定義介面,儲存事務定義的各種屬性,如超時時間、隔離級別、傳播屬性等。 public interface TransactionDefinition { //獲取事務傳播型別
Spring事務原始碼分析專題(一)JdbcTemplate使用及原始碼分析
Spring中的資料訪問,JdbcTemplate使用及原始碼分析 # 前言 本系列文章為事務專欄分析文章,整個事務分析專題將按下面這張圖完成 ![image-20200718220712800](https://gitee.com/wx_cc347be696/blogImage/raw/master
【筆記】Spring 事務原理分析和原始碼剖析
概述 事務處理是一個重要並且涉及範圍很廣的領域,涉及到併發和資料一致性方面的問題。作為應用平臺的 Spring 具有在多種環境中配置和使用事務處理的能力,也就是說通過使用 Spring 的事務處理,可以把事務處理的工作統一起來,為事務處理提供統一支援。 由於這
Spring 宣告式事務原始碼分析
Spring 的宣告式事務實現方式主要有2種,一種為通過使用Spring的< tx:advice >定義事務通知與AOP相關配置實現,另為一種通過@Transactional實現事務管理實現,個人認為本質上其實都一樣,就是用定義的註解或者配置資訊將目
Spring AOP原始碼分析
概述 定義 官方定義:Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about prog
Spring IOC原始碼分析
Spring IOC原始碼分析 Spring 應用 1 注入巢狀Bean 在Spring中,如果某個Bean所依賴的Bean不想被Spring容器直接訪問,可以使用巢狀Bean。和普通的Bean一樣,使用元素來定義巢狀的Bean,巢狀Bean只對它的外部的Bean有效,Sprin
Spring-AOP原始碼分析
一、概述 Spring的兩大特性:IOC和AOP。 AOP是面向切面程式設計,Spring內建了自己實現的基於動態代理技術的AOP,同時還支援成熟的AspectJ框架,我們這裡主要講述的還是內建的基於動態代理的AOP實現。因為面對一些普通的需求,Spring內建的AOP已經綽綽有餘。
關於spring事務原始碼的一些小理解
1、spring事務的簡單概述 由於實現事務功能的方式各不相同,Spring進行了統一的抽象,形成了PlatformTransactionManager事務管理器頂級介面(平臺事務管理器),事務的提交、回滾等操作全部交給它來實現 先來看下三大介面 PlatformTransactionManage
Spring Ioc 原始碼分析之Bean的載入和構造
我們都知道,Spring Ioc和Aop是Spring的核心的功能,因此花一點時間去研究還是很有意義的,如果僅僅是知其所以然,也就體會不到大師設計Spring的精華,還記得那句話,Spring為JavaEE開發帶來了春天。IOC就是Inversion of control 也就是控制反轉的意思,另一種稱呼叫做
Spring-BeanFactory原始碼分析(一)
前言 Spring 版本:5.0.9.RELEASE 正式進入Spring 原始碼分析這個模組了,對於spring這個龐大的工程,如果要一點點的完全分析是非常困難的,對於應用型框架,我還是偏向於掌握思想或者設計,而不是記住程式碼,對於初次看spring原始
Spring Cloud原始碼分析之Eureka篇第六章:服務註冊
在文章《Spring Cloud原始碼分析之Eureka篇第四章:服務註冊是如何發起的 》的分析中,我們知道了作為Eureka Client的應用啟動時,在com.netflix.discovery.DiscoveryClient類的initScheduledT
Spring MVC原始碼分析(一)
一、Servlet Spring MVC中核心Servlet(DispatcherServlet)的繼承結構 圖示(C)表示是類,而圖示(I)表示介面 而上圖的其中HttpServlet、GenericServlet、Servlet、ServletConfi
【轉】Spring AMQP 原始碼分析 05
### 準備 ## 目標 瞭解 Spring AMQP Message Listener 如何處理異常 ## 前置知識 《Spring AMQP 原始碼分析 04 - MessageListener》 ## 相關資源 原始碼版本:Spring AMQP
【轉】Spring AMQP 原始碼分析 04
### 準備 ## 目標 瞭解 Spring AMQP 如何實現非同步訊息投遞(推模式) ## 前置知識 《RabbitMQ入門_05_多執行緒消費同一佇列》 ## 相關資源 原始碼版本:Spring AMQP 1.7.3.RELEASE ## 測試
【轉】Spring AMQP 原始碼分析 03
### 準備 ## 目標 瞭解 Spring AMQP 訊息轉化實現 ## 相關資源 ## 測試程式碼 gordon.study.rabbitmq.springamqp.JsonMessage.java ### 分析 ## Mes
Spring Cloud原始碼分析之Eureka篇第八章:服務註冊名稱的來歷
關於服務註冊名稱 服務註冊名稱,是指Eureka client註冊到Eureka server時,用於標記自己身份的標誌,舉例說明,以下是個簡單的Eureka client配置: server: port: 8082 spring: applicatio
Spring Boot 原始碼分析
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Boot致力於在蓬勃發展的快速應用開發領域(rapid application d
Spring事務原始碼梳理
通過註解@EnableTransactionManagement中的@Import(TransactionManagementConfigurationSelector.class)給容器中匯入了兩個元件,分別是:AutoProxyRegistrar和ProxyTransactionManagement
spring--aop_2_原始碼分析之MethodInterceptor
前提: 前兩篇分析了aop 兩種方式實現的大致流程和方式,在這兩種實現方式中都有一個很重要的方法獲取攔截器鏈 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionA
【spring】原始碼分析 一 從ContextLoaderListener開始·
原始碼環境 : idea + spring 4.3.4 +tomcat7 + gradle附 : 基於 java 註解的 配置元資料 的 web.xml 配置做參考(spring 3.0 後支援)<?xml version="1.0" encoding="UTF-8"