[{"data":1,"prerenderedAt":2337},["ShallowReactive",2],{"blog:\u002Fblog\u002F2021\u002F11\u002F07\u002Fspring-transaction-core-implementation\u002F":3},{"id":4,"title":5,"body":6,"categories":2322,"comments":2324,"date":2325,"description":2326,"draft":2327,"extension":2328,"legacySlug":2329,"meta":2330,"navigation":2324,"path":2331,"seo":2332,"stem":2333,"tags":2334,"updated":2335,"__hash__":2336},"blog\u002Fblog\u002F2021\u002F11\u002F07\u002Fspring-transaction-core-implementation.md","spring：声明式事务源码",{"type":7,"value":8,"toc":2317},"minimark",[9,13,18,26,33,75,89,93,98,103,427,432,746,751,956,959,998,1001,1006,1139,1144,1446,1449,1453,1458,1601,1606,2002,2006,2011,2313],[10,11,12],"p",{},"本文主要介绍spring事务（JDBC单数据库事务管理）的核心源码实现",[14,15,17],"h1",{"id":16},"_1核心类介绍","1、核心类介绍",[10,19,20,21],{},"我们可以先看一下核心类图。\n",[22,23],"img",{"alt":24,"src":25},"spring-transaction-core-class","\u002Fblog-assets\u002Fspring-transaction-core-implementation\u002Fspring-transaction-core-class.png",[27,28,29],"ul",{},[30,31,32],"li",{},"PlatformTransactionManager\n底层接口，定义事务方法",[34,35,40],"pre",{"className":36,"code":37,"language":38,"meta":39,"style":39},"language-java shiki shiki-themes github-light github-dark","public interface PlatformTransactionManager extends TransactionManager {  \n    TransactionStatus getTransaction(@Nullable TransactionDefinition definition) \n    void commit(TransactionStatus status) throws TransactionException;\n    void rollback(TransactionStatus status) throws TransactionException;\n}\n","java","",[41,42,43,51,57,63,69],"code",{"__ignoreMap":39},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,50],{},"public interface PlatformTransactionManager extends TransactionManager {  \n",[44,52,54],{"class":46,"line":53},2,[44,55,56],{},"    TransactionStatus getTransaction(@Nullable TransactionDefinition definition) \n",[44,58,60],{"class":46,"line":59},3,[44,61,62],{},"    void commit(TransactionStatus status) throws TransactionException;\n",[44,64,66],{"class":46,"line":65},4,[44,67,68],{},"    void rollback(TransactionStatus status) throws TransactionException;\n",[44,70,72],{"class":46,"line":71},5,[44,73,74],{},"}\n",[27,76,77,80,83,86],{},[30,78,79],{},"AbstractPlatformTransactionManager\n抽象类，实现PlatformTransactionManager接口，并定义了一些抽象方法比如doCommit、doRollback留给子类实现（这里使用了设计模式中的模板模式）。",[30,81,82],{},"DataSourceTransactionmanager\nJDBC单数据库事务管理器，基于Connection实现",[30,84,85],{},"JtaTransactionManager\n分布式事务管理器（本文不展开介绍）",[30,87,88],{},"KafkaTransactionManager\nKafka事务管理器（本文不展开介绍）",[14,90,92],{"id":91},"_2核心方法实现","2、核心方法实现",[94,95,97],"h2",{"id":96},"_21gettransaction获取事务","2.1、getTransaction获取事务",[27,99,100],{},[30,101,102],{},"AbstractPlatformTransactionManager.getTransaction实现",[34,104,106],{"className":36,"code":105,"language":38,"meta":39,"style":39},"@Override  \npublic final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)  \n       throws TransactionException {  \n  \n    \u002F\u002F Use defaults if no transaction definition given.  \n    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());  \n  \n    \u002F\u002F模板模式，由子类实现  \n    Object transaction = doGetTransaction();  \n    boolean debugEnabled = logger.isDebugEnabled();  \n  \n    \u002F\u002F当前已存在事务  \n    if (isExistingTransaction(transaction)) {  \n       \u002F\u002F Existing transaction found -> check propagation behavior to find out how to behave.  \n       return handleExistingTransaction(def, transaction, debugEnabled);  \n    }  \n  \n    \u002F\u002F Check definition settings for new transaction.  \n    if (def.getTimeout() \u003C TransactionDefinition.TIMEOUT_DEFAULT) {  \n       throw new InvalidTimeoutException(\"Invalid transaction timeout\", def.getTimeout());  \n    }  \n  \n    \u002F\u002F No existing transaction found -> check propagation behavior to find out how to proceed.  \n    \u002F\u002F传播类型为MANDATORY(强制性的)，如果当前无事务则抛出异常  \n    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {  \n       throw new IllegalTransactionStateException(  \n             \"No existing transaction found for transaction marked with propagation 'mandatory'\");  \n    }  \n    \u002F\u002F传播类型为REQUIRED、REQUIRES_NEW、NESTED则新开启一个事务  \n    else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||  \n          def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||  \n          def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {  \n       SuspendedResourcesHolder suspendedResources = suspend(null);  \n       if (debugEnabled) {  \n          logger.debug(\"Creating new transaction with name [\" + def.getName() + \"]: \" + def);  \n       }  \n       try {  \n          return startTransaction(def, transaction, debugEnabled, suspendedResources);  \n       }  \n       catch (RuntimeException | Error ex) {  \n          resume(null, suspendedResources);  \n          throw ex;  \n       }  \n    }  \n    \u002F\u002F传播类型为SUPPORTS、NOT_SUPPORTED、NEVER  \n    else {  \n       \u002F\u002F Create \"empty\" transaction: no actual transaction, but potentially synchronization.  \n       \u002F\u002F如果当前事务隔离级别不是-1，并且开启warn提醒，则打印一条warn日T志  \n       if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {  \n          logger.warn(\"Custom isolation level specified but no actual transaction initiated; \" +  \n                \"isolation level will effectively be ignored: \" + def);  \n       }  \n       boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);  \n       return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);  \n    }  \n}\n",[41,107,108,113,118,123,128,133,139,144,150,156,162,167,173,179,185,191,197,202,208,214,220,225,230,236,242,248,254,260,265,271,277,283,289,295,301,307,313,319,325,330,336,342,348,353,358,364,370,376,382,388,394,400,405,411,417,422],{"__ignoreMap":39},[44,109,110],{"class":46,"line":47},[44,111,112],{},"@Override  \n",[44,114,115],{"class":46,"line":53},[44,116,117],{},"public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)  \n",[44,119,120],{"class":46,"line":59},[44,121,122],{},"       throws TransactionException {  \n",[44,124,125],{"class":46,"line":65},[44,126,127],{},"  \n",[44,129,130],{"class":46,"line":71},[44,131,132],{},"    \u002F\u002F Use defaults if no transaction definition given.  \n",[44,134,136],{"class":46,"line":135},6,[44,137,138],{},"    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());  \n",[44,140,142],{"class":46,"line":141},7,[44,143,127],{},[44,145,147],{"class":46,"line":146},8,[44,148,149],{},"    \u002F\u002F模板模式，由子类实现  \n",[44,151,153],{"class":46,"line":152},9,[44,154,155],{},"    Object transaction = doGetTransaction();  \n",[44,157,159],{"class":46,"line":158},10,[44,160,161],{},"    boolean debugEnabled = logger.isDebugEnabled();  \n",[44,163,165],{"class":46,"line":164},11,[44,166,127],{},[44,168,170],{"class":46,"line":169},12,[44,171,172],{},"    \u002F\u002F当前已存在事务  \n",[44,174,176],{"class":46,"line":175},13,[44,177,178],{},"    if (isExistingTransaction(transaction)) {  \n",[44,180,182],{"class":46,"line":181},14,[44,183,184],{},"       \u002F\u002F Existing transaction found -> check propagation behavior to find out how to behave.  \n",[44,186,188],{"class":46,"line":187},15,[44,189,190],{},"       return handleExistingTransaction(def, transaction, debugEnabled);  \n",[44,192,194],{"class":46,"line":193},16,[44,195,196],{},"    }  \n",[44,198,200],{"class":46,"line":199},17,[44,201,127],{},[44,203,205],{"class":46,"line":204},18,[44,206,207],{},"    \u002F\u002F Check definition settings for new transaction.  \n",[44,209,211],{"class":46,"line":210},19,[44,212,213],{},"    if (def.getTimeout() \u003C TransactionDefinition.TIMEOUT_DEFAULT) {  \n",[44,215,217],{"class":46,"line":216},20,[44,218,219],{},"       throw new InvalidTimeoutException(\"Invalid transaction timeout\", def.getTimeout());  \n",[44,221,223],{"class":46,"line":222},21,[44,224,196],{},[44,226,228],{"class":46,"line":227},22,[44,229,127],{},[44,231,233],{"class":46,"line":232},23,[44,234,235],{},"    \u002F\u002F No existing transaction found -> check propagation behavior to find out how to proceed.  \n",[44,237,239],{"class":46,"line":238},24,[44,240,241],{},"    \u002F\u002F传播类型为MANDATORY(强制性的)，如果当前无事务则抛出异常  \n",[44,243,245],{"class":46,"line":244},25,[44,246,247],{},"    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {  \n",[44,249,251],{"class":46,"line":250},26,[44,252,253],{},"       throw new IllegalTransactionStateException(  \n",[44,255,257],{"class":46,"line":256},27,[44,258,259],{},"             \"No existing transaction found for transaction marked with propagation 'mandatory'\");  \n",[44,261,263],{"class":46,"line":262},28,[44,264,196],{},[44,266,268],{"class":46,"line":267},29,[44,269,270],{},"    \u002F\u002F传播类型为REQUIRED、REQUIRES_NEW、NESTED则新开启一个事务  \n",[44,272,274],{"class":46,"line":273},30,[44,275,276],{},"    else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||  \n",[44,278,280],{"class":46,"line":279},31,[44,281,282],{},"          def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||  \n",[44,284,286],{"class":46,"line":285},32,[44,287,288],{},"          def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {  \n",[44,290,292],{"class":46,"line":291},33,[44,293,294],{},"       SuspendedResourcesHolder suspendedResources = suspend(null);  \n",[44,296,298],{"class":46,"line":297},34,[44,299,300],{},"       if (debugEnabled) {  \n",[44,302,304],{"class":46,"line":303},35,[44,305,306],{},"          logger.debug(\"Creating new transaction with name [\" + def.getName() + \"]: \" + def);  \n",[44,308,310],{"class":46,"line":309},36,[44,311,312],{},"       }  \n",[44,314,316],{"class":46,"line":315},37,[44,317,318],{},"       try {  \n",[44,320,322],{"class":46,"line":321},38,[44,323,324],{},"          return startTransaction(def, transaction, debugEnabled, suspendedResources);  \n",[44,326,328],{"class":46,"line":327},39,[44,329,312],{},[44,331,333],{"class":46,"line":332},40,[44,334,335],{},"       catch (RuntimeException | Error ex) {  \n",[44,337,339],{"class":46,"line":338},41,[44,340,341],{},"          resume(null, suspendedResources);  \n",[44,343,345],{"class":46,"line":344},42,[44,346,347],{},"          throw ex;  \n",[44,349,351],{"class":46,"line":350},43,[44,352,312],{},[44,354,356],{"class":46,"line":355},44,[44,357,196],{},[44,359,361],{"class":46,"line":360},45,[44,362,363],{},"    \u002F\u002F传播类型为SUPPORTS、NOT_SUPPORTED、NEVER  \n",[44,365,367],{"class":46,"line":366},46,[44,368,369],{},"    else {  \n",[44,371,373],{"class":46,"line":372},47,[44,374,375],{},"       \u002F\u002F Create \"empty\" transaction: no actual transaction, but potentially synchronization.  \n",[44,377,379],{"class":46,"line":378},48,[44,380,381],{},"       \u002F\u002F如果当前事务隔离级别不是-1，并且开启warn提醒，则打印一条warn日T志  \n",[44,383,385],{"class":46,"line":384},49,[44,386,387],{},"       if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {  \n",[44,389,391],{"class":46,"line":390},50,[44,392,393],{},"          logger.warn(\"Custom isolation level specified but no actual transaction initiated; \" +  \n",[44,395,397],{"class":46,"line":396},51,[44,398,399],{},"                \"isolation level will effectively be ignored: \" + def);  \n",[44,401,403],{"class":46,"line":402},52,[44,404,312],{},[44,406,408],{"class":46,"line":407},53,[44,409,410],{},"       boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);  \n",[44,412,414],{"class":46,"line":413},54,[44,415,416],{},"       return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);  \n",[44,418,420],{"class":46,"line":419},55,[44,421,196],{},[44,423,425],{"class":46,"line":424},56,[44,426,74],{},[27,428,429],{},[30,430,431],{},"AbstractPlatformTransactionManager.handleExistingTransaction实现\n该方法用于处理当前已存在事务的情况",[34,433,435],{"className":36,"code":434,"language":38,"meta":39,"style":39},"private TransactionStatus handleExistingTransaction(  \n       TransactionDefinition definition, Object transaction, boolean debugEnabled)  \n       throws TransactionException {  \n  \n    \u002F\u002F事务传播类型为NEVER，抛出异常  \n    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {  \n       throw new IllegalTransactionStateException(  \n             \"Existing transaction found for transaction marked with propagation 'never'\");  \n    }  \n  \n    \u002F\u002F事务传播类型为NOT_SUPPORTED，挂起当前事务  \n    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {  \n       if (debugEnabled) {  \n          logger.debug(\"Suspending current transaction\");  \n       }  \n       \u002F\u002F挂起当前事务  \n       Object suspendedResources = suspend(transaction);  \n       boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);  \n       \u002F\u002F创建空事务  \n       return prepareTransactionStatus(  \n             definition, null, false, newSynchronization, debugEnabled, suspendedResources);  \n    }  \n  \n    \u002F\u002F事务传播类型为REQUIRES_NEW，挂起当前事务，开启新事物  \n    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {  \n       if (debugEnabled) {  \n          logger.debug(\"Suspending current transaction, creating new transaction with name [\" +  \n                definition.getName() + \"]\");  \n       }  \n       SuspendedResourcesHolder suspendedResources = suspend(transaction);  \n       try {  \n          return startTransaction(definition, transaction, debugEnabled, suspendedResources);  \n       }  \n       catch (RuntimeException | Error beginEx) {  \n          resumeAfterBeginException(transaction, suspendedResources, beginEx);  \n          throw beginEx;  \n       }  \n    }  \n  \n    \u002F\u002F事务传播类型为NESTED  \n    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {  \n       if (!isNestedTransactionAllowed()) {  \n          throw new NestedTransactionNotSupportedException(  \n                \"Transaction manager does not allow nested transactions by default - \" +  \n                \"specify 'nestedTransactionAllowed' property with value 'true'\");  \n       }  \n       if (debugEnabled) {  \n          logger.debug(\"Creating nested transaction with name [\" + definition.getName() + \"]\");  \n       }  \n       if (useSavepointForNestedTransaction()) {  \n          \u002F\u002F Create savepoint within existing Spring-managed transaction,  \n          \u002F\u002F through the SavepointManager API implemented by TransactionStatus.          \u002F\u002F Usually uses JDBC savepoints. Never activates Spring synchronization.          \u002F\u002F创建一个保存点  \n          DefaultTransactionStatus status =  \n                prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);  \n          status.createAndHoldSavepoint();  \n          return status;  \n       }  \n       else {  \n          \u002F\u002F Nested transaction through nested begin and commit\u002Frollback calls.  \n          \u002F\u002F Usually only for JTA: Spring synchronization might get activated here          \u002F\u002F in case of a pre-existing JTA transaction.          \n          return startTransaction(definition, transaction, debugEnabled, null);  \n       }  \n    }\n",[41,436,437,442,447,451,455,460,465,469,474,478,482,487,492,496,501,505,510,515,519,524,529,534,538,542,547,552,556,561,566,570,575,579,584,588,593,598,603,607,611,615,620,625,630,635,640,645,649,653,658,662,667,672,683,688,693,698,703,708,714,720,729,735,740],{"__ignoreMap":39},[44,438,439],{"class":46,"line":47},[44,440,441],{},"private TransactionStatus handleExistingTransaction(  \n",[44,443,444],{"class":46,"line":53},[44,445,446],{},"       TransactionDefinition definition, Object transaction, boolean debugEnabled)  \n",[44,448,449],{"class":46,"line":59},[44,450,122],{},[44,452,453],{"class":46,"line":65},[44,454,127],{},[44,456,457],{"class":46,"line":71},[44,458,459],{},"    \u002F\u002F事务传播类型为NEVER，抛出异常  \n",[44,461,462],{"class":46,"line":135},[44,463,464],{},"    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {  \n",[44,466,467],{"class":46,"line":141},[44,468,253],{},[44,470,471],{"class":46,"line":146},[44,472,473],{},"             \"Existing transaction found for transaction marked with propagation 'never'\");  \n",[44,475,476],{"class":46,"line":152},[44,477,196],{},[44,479,480],{"class":46,"line":158},[44,481,127],{},[44,483,484],{"class":46,"line":164},[44,485,486],{},"    \u002F\u002F事务传播类型为NOT_SUPPORTED，挂起当前事务  \n",[44,488,489],{"class":46,"line":169},[44,490,491],{},"    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {  \n",[44,493,494],{"class":46,"line":175},[44,495,300],{},[44,497,498],{"class":46,"line":181},[44,499,500],{},"          logger.debug(\"Suspending current transaction\");  \n",[44,502,503],{"class":46,"line":187},[44,504,312],{},[44,506,507],{"class":46,"line":193},[44,508,509],{},"       \u002F\u002F挂起当前事务  \n",[44,511,512],{"class":46,"line":199},[44,513,514],{},"       Object suspendedResources = suspend(transaction);  \n",[44,516,517],{"class":46,"line":204},[44,518,410],{},[44,520,521],{"class":46,"line":210},[44,522,523],{},"       \u002F\u002F创建空事务  \n",[44,525,526],{"class":46,"line":216},[44,527,528],{},"       return prepareTransactionStatus(  \n",[44,530,531],{"class":46,"line":222},[44,532,533],{},"             definition, null, false, newSynchronization, debugEnabled, suspendedResources);  \n",[44,535,536],{"class":46,"line":227},[44,537,196],{},[44,539,540],{"class":46,"line":232},[44,541,127],{},[44,543,544],{"class":46,"line":238},[44,545,546],{},"    \u002F\u002F事务传播类型为REQUIRES_NEW，挂起当前事务，开启新事物  \n",[44,548,549],{"class":46,"line":244},[44,550,551],{},"    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {  \n",[44,553,554],{"class":46,"line":250},[44,555,300],{},[44,557,558],{"class":46,"line":256},[44,559,560],{},"          logger.debug(\"Suspending current transaction, creating new transaction with name [\" +  \n",[44,562,563],{"class":46,"line":262},[44,564,565],{},"                definition.getName() + \"]\");  \n",[44,567,568],{"class":46,"line":267},[44,569,312],{},[44,571,572],{"class":46,"line":273},[44,573,574],{},"       SuspendedResourcesHolder suspendedResources = suspend(transaction);  \n",[44,576,577],{"class":46,"line":279},[44,578,318],{},[44,580,581],{"class":46,"line":285},[44,582,583],{},"          return startTransaction(definition, transaction, debugEnabled, suspendedResources);  \n",[44,585,586],{"class":46,"line":291},[44,587,312],{},[44,589,590],{"class":46,"line":297},[44,591,592],{},"       catch (RuntimeException | Error beginEx) {  \n",[44,594,595],{"class":46,"line":303},[44,596,597],{},"          resumeAfterBeginException(transaction, suspendedResources, beginEx);  \n",[44,599,600],{"class":46,"line":309},[44,601,602],{},"          throw beginEx;  \n",[44,604,605],{"class":46,"line":315},[44,606,312],{},[44,608,609],{"class":46,"line":321},[44,610,196],{},[44,612,613],{"class":46,"line":327},[44,614,127],{},[44,616,617],{"class":46,"line":332},[44,618,619],{},"    \u002F\u002F事务传播类型为NESTED  \n",[44,621,622],{"class":46,"line":338},[44,623,624],{},"    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {  \n",[44,626,627],{"class":46,"line":344},[44,628,629],{},"       if (!isNestedTransactionAllowed()) {  \n",[44,631,632],{"class":46,"line":350},[44,633,634],{},"          throw new NestedTransactionNotSupportedException(  \n",[44,636,637],{"class":46,"line":355},[44,638,639],{},"                \"Transaction manager does not allow nested transactions by default - \" +  \n",[44,641,642],{"class":46,"line":360},[44,643,644],{},"                \"specify 'nestedTransactionAllowed' property with value 'true'\");  \n",[44,646,647],{"class":46,"line":366},[44,648,312],{},[44,650,651],{"class":46,"line":372},[44,652,300],{},[44,654,655],{"class":46,"line":378},[44,656,657],{},"          logger.debug(\"Creating nested transaction with name [\" + definition.getName() + \"]\");  \n",[44,659,660],{"class":46,"line":384},[44,661,312],{},[44,663,664],{"class":46,"line":390},[44,665,666],{},"       if (useSavepointForNestedTransaction()) {  \n",[44,668,669],{"class":46,"line":396},[44,670,671],{},"          \u002F\u002F Create savepoint within existing Spring-managed transaction,  \n",[44,673,674,677,680],{"class":46,"line":402},[44,675,676],{},"          \u002F\u002F through the SavepointManager API implemented by TransactionStatus.",[44,678,679],{},"          \u002F\u002F Usually uses JDBC savepoints. Never activates Spring synchronization.",[44,681,682],{},"          \u002F\u002F创建一个保存点  \n",[44,684,685],{"class":46,"line":407},[44,686,687],{},"          DefaultTransactionStatus status =  \n",[44,689,690],{"class":46,"line":413},[44,691,692],{},"                prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);  \n",[44,694,695],{"class":46,"line":419},[44,696,697],{},"          status.createAndHoldSavepoint();  \n",[44,699,700],{"class":46,"line":424},[44,701,702],{},"          return status;  \n",[44,704,706],{"class":46,"line":705},57,[44,707,312],{},[44,709,711],{"class":46,"line":710},58,[44,712,713],{},"       else {  \n",[44,715,717],{"class":46,"line":716},59,[44,718,719],{},"          \u002F\u002F Nested transaction through nested begin and commit\u002Frollback calls.  \n",[44,721,723,726],{"class":46,"line":722},60,[44,724,725],{},"          \u002F\u002F Usually only for JTA: Spring synchronization might get activated here",[44,727,728],{},"          \u002F\u002F in case of a pre-existing JTA transaction.          \n",[44,730,732],{"class":46,"line":731},61,[44,733,734],{},"          return startTransaction(definition, transaction, debugEnabled, null);  \n",[44,736,738],{"class":46,"line":737},62,[44,739,312],{},[44,741,743],{"class":46,"line":742},63,[44,744,745],{},"    }\n",[27,747,748],{},[30,749,750],{},"AbstractPlatformTransactionManager.suspend\n事务挂起",[34,752,754],{"className":36,"code":753,"language":38,"meta":39,"style":39},"protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {  \n    \u002F\u002F判断事务同步状态是否激活  \n    if (TransactionSynchronizationManager.isSynchronizationActive()) {  \n       List\u003CTransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();  \n       try {  \n          Object suspendedResources = null;  \n          if (transaction != null) {  \n             \u002F\u002F挂起当前事务  \n             suspendedResources = doSuspend(transaction);  \n          }  \n          String name = TransactionSynchronizationManager.getCurrentTransactionName();  \n          \u002F\u002F清空当前事务名称  \n          TransactionSynchronizationManager.setCurrentTransactionName(null);  \n          boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();  \n          \u002F\u002FreadOnly置为false  \n          TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);  \n          Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();  \n          \u002F\u002F事务隔离级别设置为null  \n          TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);  \n          boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();  \n          \u002F\u002F事务实际活跃状态设置为false  \n          TransactionSynchronizationManager.setActualTransactionActive(false);  \n          return new SuspendedResourcesHolder(  \n                suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);  \n       }  \n       catch (RuntimeException | Error ex) {  \n          \u002F\u002F doSuspend failed - original transaction is still active...  \n          \u002F\u002F异常情况恢复同步信息  \n          doResumeSynchronization(suspendedSynchronizations);  \n          throw ex;  \n       }  \n    }  \n    else if (transaction != null) {  \n       \u002F\u002F Transaction active but no synchronization active.  \n       Object suspendedResources = doSuspend(transaction);  \n       return new SuspendedResourcesHolder(suspendedResources);  \n    }  \n    else {  \n       \u002F\u002F Neither transaction nor synchronization active.  \n       return null;  \n    }  \n}\n",[41,755,756,761,766,771,776,780,785,790,795,800,805,810,815,820,825,830,835,840,845,850,855,860,865,870,875,879,883,888,893,898,902,906,910,915,920,925,930,934,938,943,948,952],{"__ignoreMap":39},[44,757,758],{"class":46,"line":47},[44,759,760],{},"protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {  \n",[44,762,763],{"class":46,"line":53},[44,764,765],{},"    \u002F\u002F判断事务同步状态是否激活  \n",[44,767,768],{"class":46,"line":59},[44,769,770],{},"    if (TransactionSynchronizationManager.isSynchronizationActive()) {  \n",[44,772,773],{"class":46,"line":65},[44,774,775],{},"       List\u003CTransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();  \n",[44,777,778],{"class":46,"line":71},[44,779,318],{},[44,781,782],{"class":46,"line":135},[44,783,784],{},"          Object suspendedResources = null;  \n",[44,786,787],{"class":46,"line":141},[44,788,789],{},"          if (transaction != null) {  \n",[44,791,792],{"class":46,"line":146},[44,793,794],{},"             \u002F\u002F挂起当前事务  \n",[44,796,797],{"class":46,"line":152},[44,798,799],{},"             suspendedResources = doSuspend(transaction);  \n",[44,801,802],{"class":46,"line":158},[44,803,804],{},"          }  \n",[44,806,807],{"class":46,"line":164},[44,808,809],{},"          String name = TransactionSynchronizationManager.getCurrentTransactionName();  \n",[44,811,812],{"class":46,"line":169},[44,813,814],{},"          \u002F\u002F清空当前事务名称  \n",[44,816,817],{"class":46,"line":175},[44,818,819],{},"          TransactionSynchronizationManager.setCurrentTransactionName(null);  \n",[44,821,822],{"class":46,"line":181},[44,823,824],{},"          boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();  \n",[44,826,827],{"class":46,"line":187},[44,828,829],{},"          \u002F\u002FreadOnly置为false  \n",[44,831,832],{"class":46,"line":193},[44,833,834],{},"          TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);  \n",[44,836,837],{"class":46,"line":199},[44,838,839],{},"          Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();  \n",[44,841,842],{"class":46,"line":204},[44,843,844],{},"          \u002F\u002F事务隔离级别设置为null  \n",[44,846,847],{"class":46,"line":210},[44,848,849],{},"          TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);  \n",[44,851,852],{"class":46,"line":216},[44,853,854],{},"          boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();  \n",[44,856,857],{"class":46,"line":222},[44,858,859],{},"          \u002F\u002F事务实际活跃状态设置为false  \n",[44,861,862],{"class":46,"line":227},[44,863,864],{},"          TransactionSynchronizationManager.setActualTransactionActive(false);  \n",[44,866,867],{"class":46,"line":232},[44,868,869],{},"          return new SuspendedResourcesHolder(  \n",[44,871,872],{"class":46,"line":238},[44,873,874],{},"                suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);  \n",[44,876,877],{"class":46,"line":244},[44,878,312],{},[44,880,881],{"class":46,"line":250},[44,882,335],{},[44,884,885],{"class":46,"line":256},[44,886,887],{},"          \u002F\u002F doSuspend failed - original transaction is still active...  \n",[44,889,890],{"class":46,"line":262},[44,891,892],{},"          \u002F\u002F异常情况恢复同步信息  \n",[44,894,895],{"class":46,"line":267},[44,896,897],{},"          doResumeSynchronization(suspendedSynchronizations);  \n",[44,899,900],{"class":46,"line":273},[44,901,347],{},[44,903,904],{"class":46,"line":279},[44,905,312],{},[44,907,908],{"class":46,"line":285},[44,909,196],{},[44,911,912],{"class":46,"line":291},[44,913,914],{},"    else if (transaction != null) {  \n",[44,916,917],{"class":46,"line":297},[44,918,919],{},"       \u002F\u002F Transaction active but no synchronization active.  \n",[44,921,922],{"class":46,"line":303},[44,923,924],{},"       Object suspendedResources = doSuspend(transaction);  \n",[44,926,927],{"class":46,"line":309},[44,928,929],{},"       return new SuspendedResourcesHolder(suspendedResources);  \n",[44,931,932],{"class":46,"line":315},[44,933,196],{},[44,935,936],{"class":46,"line":321},[44,937,369],{},[44,939,940],{"class":46,"line":327},[44,941,942],{},"       \u002F\u002F Neither transaction nor synchronization active.  \n",[44,944,945],{"class":46,"line":332},[44,946,947],{},"       return null;  \n",[44,949,950],{"class":46,"line":338},[44,951,196],{},[44,953,954],{"class":46,"line":344},[44,955,74],{},[10,957,958],{},"其中doSuspend会执行当前事务的挂起操作，AbstractPlatformTransactionManager抽象类doSuspend()会直接抛出异常，依赖于具体事务执行器的实现，DataSourceTransactionManager实现如下：",[34,960,962],{"className":36,"code":961,"language":38,"meta":39,"style":39},"protected Object doSuspend(Object transaction) {  \n    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  \n    \u002F\u002F连接持有对象置为null  \n    txObject.setConnectionHolder(null);  \n    \u002F\u002F删除datasource  \n    return TransactionSynchronizationManager.unbindResource(obtainDataSource());  \n}\n",[41,963,964,969,974,979,984,989,994],{"__ignoreMap":39},[44,965,966],{"class":46,"line":47},[44,967,968],{},"protected Object doSuspend(Object transaction) {  \n",[44,970,971],{"class":46,"line":53},[44,972,973],{},"    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  \n",[44,975,976],{"class":46,"line":59},[44,977,978],{},"    \u002F\u002F连接持有对象置为null  \n",[44,980,981],{"class":46,"line":65},[44,982,983],{},"    txObject.setConnectionHolder(null);  \n",[44,985,986],{"class":46,"line":71},[44,987,988],{},"    \u002F\u002F删除datasource  \n",[44,990,991],{"class":46,"line":135},[44,992,993],{},"    return TransactionSynchronizationManager.unbindResource(obtainDataSource());  \n",[44,995,996],{"class":46,"line":141},[44,997,74],{},[10,999,1000],{},"其中核心操作包含两步\n1、当前事务清空ConnectionHolder\n2、当前线程解绑datasource（ThreadLocal中移除resources对应的key）",[27,1002,1003],{},[30,1004,1005],{},"TransactionSynchronizationManager\n事务同步管理器，该类维护了多个线程本地变量ThreadLocal，如下所示：",[34,1007,1009],{"className":36,"code":1008,"language":38,"meta":39,"style":39},"public abstract class TransactionSynchronizationManager {  \n  \n    \u002F\u002F事务资源  \n    private static final ThreadLocal\u003CMap\u003CObject, Object>> resources =  \n          new NamedThreadLocal\u003C>(\"Transactional resources\");  \n  \n    \u002F\u002F事务同步信息  \n    private static final ThreadLocal\u003CSet\u003CTransactionSynchronization>> synchronizations =  \n          new NamedThreadLocal\u003C>(\"Transaction synchronizations\");  \n  \n    \u002F\u002F当前事务名称  \n    private static final ThreadLocal\u003CString> currentTransactionName =  \n          new NamedThreadLocal\u003C>(\"Current transaction name\");  \n  \n    \u002F\u002F事务只读状态  \n    private static final ThreadLocal\u003CBoolean> currentTransactionReadOnly =  \n          new NamedThreadLocal\u003C>(\"Current transaction read-only status\");  \n  \n    \u002F\u002F事务隔离级别  \n    private static final ThreadLocal\u003CInteger> currentTransactionIsolationLevel =  \n          new NamedThreadLocal\u003C>(\"Current transaction isolation level\");  \n  \n    \u002F\u002F事务活跃状态  \n    private static final ThreadLocal\u003CBoolean> actualTransactionActive =  \n          new NamedThreadLocal\u003C>(\"Actual transaction active\");\n    \u002F\u002F......\n}\n",[41,1010,1011,1016,1020,1025,1030,1035,1039,1044,1049,1054,1058,1063,1068,1073,1077,1082,1087,1092,1096,1101,1106,1111,1115,1120,1125,1130,1135],{"__ignoreMap":39},[44,1012,1013],{"class":46,"line":47},[44,1014,1015],{},"public abstract class TransactionSynchronizationManager {  \n",[44,1017,1018],{"class":46,"line":53},[44,1019,127],{},[44,1021,1022],{"class":46,"line":59},[44,1023,1024],{},"    \u002F\u002F事务资源  \n",[44,1026,1027],{"class":46,"line":65},[44,1028,1029],{},"    private static final ThreadLocal\u003CMap\u003CObject, Object>> resources =  \n",[44,1031,1032],{"class":46,"line":71},[44,1033,1034],{},"          new NamedThreadLocal\u003C>(\"Transactional resources\");  \n",[44,1036,1037],{"class":46,"line":135},[44,1038,127],{},[44,1040,1041],{"class":46,"line":141},[44,1042,1043],{},"    \u002F\u002F事务同步信息  \n",[44,1045,1046],{"class":46,"line":146},[44,1047,1048],{},"    private static final ThreadLocal\u003CSet\u003CTransactionSynchronization>> synchronizations =  \n",[44,1050,1051],{"class":46,"line":152},[44,1052,1053],{},"          new NamedThreadLocal\u003C>(\"Transaction synchronizations\");  \n",[44,1055,1056],{"class":46,"line":158},[44,1057,127],{},[44,1059,1060],{"class":46,"line":164},[44,1061,1062],{},"    \u002F\u002F当前事务名称  \n",[44,1064,1065],{"class":46,"line":169},[44,1066,1067],{},"    private static final ThreadLocal\u003CString> currentTransactionName =  \n",[44,1069,1070],{"class":46,"line":175},[44,1071,1072],{},"          new NamedThreadLocal\u003C>(\"Current transaction name\");  \n",[44,1074,1075],{"class":46,"line":181},[44,1076,127],{},[44,1078,1079],{"class":46,"line":187},[44,1080,1081],{},"    \u002F\u002F事务只读状态  \n",[44,1083,1084],{"class":46,"line":193},[44,1085,1086],{},"    private static final ThreadLocal\u003CBoolean> currentTransactionReadOnly =  \n",[44,1088,1089],{"class":46,"line":199},[44,1090,1091],{},"          new NamedThreadLocal\u003C>(\"Current transaction read-only status\");  \n",[44,1093,1094],{"class":46,"line":204},[44,1095,127],{},[44,1097,1098],{"class":46,"line":210},[44,1099,1100],{},"    \u002F\u002F事务隔离级别  \n",[44,1102,1103],{"class":46,"line":216},[44,1104,1105],{},"    private static final ThreadLocal\u003CInteger> currentTransactionIsolationLevel =  \n",[44,1107,1108],{"class":46,"line":222},[44,1109,1110],{},"          new NamedThreadLocal\u003C>(\"Current transaction isolation level\");  \n",[44,1112,1113],{"class":46,"line":227},[44,1114,127],{},[44,1116,1117],{"class":46,"line":232},[44,1118,1119],{},"    \u002F\u002F事务活跃状态  \n",[44,1121,1122],{"class":46,"line":238},[44,1123,1124],{},"    private static final ThreadLocal\u003CBoolean> actualTransactionActive =  \n",[44,1126,1127],{"class":46,"line":244},[44,1128,1129],{},"          new NamedThreadLocal\u003C>(\"Actual transaction active\");\n",[44,1131,1132],{"class":46,"line":250},[44,1133,1134],{},"    \u002F\u002F......\n",[44,1136,1137],{"class":46,"line":256},[44,1138,74],{},[27,1140,1141],{},[30,1142,1143],{},"DataSourceTransactionManager.doBegin",[34,1145,1147],{"className":36,"code":1146,"language":38,"meta":39,"style":39},"protected void doBegin(Object transaction, TransactionDefinition definition) {  \n    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  \n    Connection con = null;  \n  \n    try {  \n       \u002F\u002F如果事务对象还没有ConnectionHolder或者其事务同步中  \n       if (!txObject.hasConnectionHolder() ||  \n             txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  \n          \u002F\u002F获取新的数据库连接对象  \n          Connection newCon = obtainDataSource().getConnection();  \n          if (logger.isDebugEnabled()) {  \n             logger.debug(\"Acquired Connection [\" + newCon + \"] for JDBC transaction\");  \n          }  \n          \u002F\u002F设置ConnectionHolder  \n          txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  \n       }  \n  \n       \u002F\u002F设置新的ConnectionHolder为事务同步中  \n       txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  \n       con = txObject.getConnectionHolder().getConnection();  \n  \n       Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  \n       \u002F\u002F设置事务隔离级别、readOnly  \n       txObject.setPreviousIsolationLevel(previousIsolationLevel);  \n       txObject.setReadOnly(definition.isReadOnly());  \n  \n       \u002F\u002F Switch to manual commit if necessary. This is very expensive in some JDBC drivers,  \n       \u002F\u002F so we don't want to do it unnecessarily (for example if we've explicitly       \u002F\u002F configured the connection pool to set it already).       if (con.getAutoCommit()) {  \n          txObject.setMustRestoreAutoCommit(true);  \n          if (logger.isDebugEnabled()) {  \n             logger.debug(\"Switching JDBC Connection [\" + con + \"] to manual commit\");  \n          }  \n          \u002F\u002F如果是自动提交切换到手动提交  \n          con.setAutoCommit(false);  \n       }  \n  \n       \u002F\u002F如果只读，执行sql设置事务为只读  \n       prepareTransactionalConnection(con, definition);  \n       \u002F\u002F设置事务active状态  \n       txObject.getConnectionHolder().setTransactionActive(true);  \n  \n       \u002F\u002F设置超时时间  \n       int timeout = determineTimeout(definition);  \n       if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  \n          txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  \n       }  \n  \n       \u002F\u002F Bind the connection holder to the thread.  \n       \u002F\u002F绑定ConnectionHolder到当前线程(thread的ThreadLocalMap)  \n       if (txObject.isNewConnectionHolder()) {  \n          TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());  \n       }  \n    }  \n  \n    catch (Throwable ex) {  \n       if (txObject.isNewConnectionHolder()) {  \n          \u002F\u002F出现异常释放连接并清空ConnectionHolder  \n          DataSourceUtils.releaseConnection(con, obtainDataSource());  \n          txObject.setConnectionHolder(null, false);  \n       }  \n       throw new CannotCreateTransactionException(\"Could not open JDBC Connection for transaction\", ex);  \n    }  \n}\n",[41,1148,1149,1154,1158,1163,1167,1172,1177,1182,1187,1192,1197,1202,1207,1211,1216,1221,1225,1229,1234,1239,1244,1248,1253,1258,1263,1268,1272,1277,1285,1290,1294,1299,1303,1308,1313,1317,1321,1326,1331,1336,1341,1345,1350,1355,1360,1365,1369,1373,1378,1383,1388,1393,1397,1401,1405,1410,1414,1419,1424,1429,1433,1438,1442],{"__ignoreMap":39},[44,1150,1151],{"class":46,"line":47},[44,1152,1153],{},"protected void doBegin(Object transaction, TransactionDefinition definition) {  \n",[44,1155,1156],{"class":46,"line":53},[44,1157,973],{},[44,1159,1160],{"class":46,"line":59},[44,1161,1162],{},"    Connection con = null;  \n",[44,1164,1165],{"class":46,"line":65},[44,1166,127],{},[44,1168,1169],{"class":46,"line":71},[44,1170,1171],{},"    try {  \n",[44,1173,1174],{"class":46,"line":135},[44,1175,1176],{},"       \u002F\u002F如果事务对象还没有ConnectionHolder或者其事务同步中  \n",[44,1178,1179],{"class":46,"line":141},[44,1180,1181],{},"       if (!txObject.hasConnectionHolder() ||  \n",[44,1183,1184],{"class":46,"line":146},[44,1185,1186],{},"             txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  \n",[44,1188,1189],{"class":46,"line":152},[44,1190,1191],{},"          \u002F\u002F获取新的数据库连接对象  \n",[44,1193,1194],{"class":46,"line":158},[44,1195,1196],{},"          Connection newCon = obtainDataSource().getConnection();  \n",[44,1198,1199],{"class":46,"line":164},[44,1200,1201],{},"          if (logger.isDebugEnabled()) {  \n",[44,1203,1204],{"class":46,"line":169},[44,1205,1206],{},"             logger.debug(\"Acquired Connection [\" + newCon + \"] for JDBC transaction\");  \n",[44,1208,1209],{"class":46,"line":175},[44,1210,804],{},[44,1212,1213],{"class":46,"line":181},[44,1214,1215],{},"          \u002F\u002F设置ConnectionHolder  \n",[44,1217,1218],{"class":46,"line":187},[44,1219,1220],{},"          txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  \n",[44,1222,1223],{"class":46,"line":193},[44,1224,312],{},[44,1226,1227],{"class":46,"line":199},[44,1228,127],{},[44,1230,1231],{"class":46,"line":204},[44,1232,1233],{},"       \u002F\u002F设置新的ConnectionHolder为事务同步中  \n",[44,1235,1236],{"class":46,"line":210},[44,1237,1238],{},"       txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  \n",[44,1240,1241],{"class":46,"line":216},[44,1242,1243],{},"       con = txObject.getConnectionHolder().getConnection();  \n",[44,1245,1246],{"class":46,"line":222},[44,1247,127],{},[44,1249,1250],{"class":46,"line":227},[44,1251,1252],{},"       Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  \n",[44,1254,1255],{"class":46,"line":232},[44,1256,1257],{},"       \u002F\u002F设置事务隔离级别、readOnly  \n",[44,1259,1260],{"class":46,"line":238},[44,1261,1262],{},"       txObject.setPreviousIsolationLevel(previousIsolationLevel);  \n",[44,1264,1265],{"class":46,"line":244},[44,1266,1267],{},"       txObject.setReadOnly(definition.isReadOnly());  \n",[44,1269,1270],{"class":46,"line":250},[44,1271,127],{},[44,1273,1274],{"class":46,"line":256},[44,1275,1276],{},"       \u002F\u002F Switch to manual commit if necessary. This is very expensive in some JDBC drivers,  \n",[44,1278,1279,1282],{"class":46,"line":262},[44,1280,1281],{},"       \u002F\u002F so we don't want to do it unnecessarily (for example if we've explicitly",[44,1283,1284],{},"       \u002F\u002F configured the connection pool to set it already).       if (con.getAutoCommit()) {  \n",[44,1286,1287],{"class":46,"line":267},[44,1288,1289],{},"          txObject.setMustRestoreAutoCommit(true);  \n",[44,1291,1292],{"class":46,"line":273},[44,1293,1201],{},[44,1295,1296],{"class":46,"line":279},[44,1297,1298],{},"             logger.debug(\"Switching JDBC Connection [\" + con + \"] to manual commit\");  \n",[44,1300,1301],{"class":46,"line":285},[44,1302,804],{},[44,1304,1305],{"class":46,"line":291},[44,1306,1307],{},"          \u002F\u002F如果是自动提交切换到手动提交  \n",[44,1309,1310],{"class":46,"line":297},[44,1311,1312],{},"          con.setAutoCommit(false);  \n",[44,1314,1315],{"class":46,"line":303},[44,1316,312],{},[44,1318,1319],{"class":46,"line":309},[44,1320,127],{},[44,1322,1323],{"class":46,"line":315},[44,1324,1325],{},"       \u002F\u002F如果只读，执行sql设置事务为只读  \n",[44,1327,1328],{"class":46,"line":321},[44,1329,1330],{},"       prepareTransactionalConnection(con, definition);  \n",[44,1332,1333],{"class":46,"line":327},[44,1334,1335],{},"       \u002F\u002F设置事务active状态  \n",[44,1337,1338],{"class":46,"line":332},[44,1339,1340],{},"       txObject.getConnectionHolder().setTransactionActive(true);  \n",[44,1342,1343],{"class":46,"line":338},[44,1344,127],{},[44,1346,1347],{"class":46,"line":344},[44,1348,1349],{},"       \u002F\u002F设置超时时间  \n",[44,1351,1352],{"class":46,"line":350},[44,1353,1354],{},"       int timeout = determineTimeout(definition);  \n",[44,1356,1357],{"class":46,"line":355},[44,1358,1359],{},"       if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  \n",[44,1361,1362],{"class":46,"line":360},[44,1363,1364],{},"          txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  \n",[44,1366,1367],{"class":46,"line":366},[44,1368,312],{},[44,1370,1371],{"class":46,"line":372},[44,1372,127],{},[44,1374,1375],{"class":46,"line":378},[44,1376,1377],{},"       \u002F\u002F Bind the connection holder to the thread.  \n",[44,1379,1380],{"class":46,"line":384},[44,1381,1382],{},"       \u002F\u002F绑定ConnectionHolder到当前线程(thread的ThreadLocalMap)  \n",[44,1384,1385],{"class":46,"line":390},[44,1386,1387],{},"       if (txObject.isNewConnectionHolder()) {  \n",[44,1389,1390],{"class":46,"line":396},[44,1391,1392],{},"          TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());  \n",[44,1394,1395],{"class":46,"line":402},[44,1396,312],{},[44,1398,1399],{"class":46,"line":407},[44,1400,196],{},[44,1402,1403],{"class":46,"line":413},[44,1404,127],{},[44,1406,1407],{"class":46,"line":419},[44,1408,1409],{},"    catch (Throwable ex) {  \n",[44,1411,1412],{"class":46,"line":424},[44,1413,1387],{},[44,1415,1416],{"class":46,"line":705},[44,1417,1418],{},"          \u002F\u002F出现异常释放连接并清空ConnectionHolder  \n",[44,1420,1421],{"class":46,"line":710},[44,1422,1423],{},"          DataSourceUtils.releaseConnection(con, obtainDataSource());  \n",[44,1425,1426],{"class":46,"line":716},[44,1427,1428],{},"          txObject.setConnectionHolder(null, false);  \n",[44,1430,1431],{"class":46,"line":722},[44,1432,312],{},[44,1434,1435],{"class":46,"line":731},[44,1436,1437],{},"       throw new CannotCreateTransactionException(\"Could not open JDBC Connection for transaction\", ex);  \n",[44,1439,1440],{"class":46,"line":737},[44,1441,196],{},[44,1443,1444],{"class":46,"line":742},[44,1445,74],{},[10,1447,1448],{},"该方法的核心操作是：\n1、获取新的数据库连接对象，设置ConnectionHolder\n2、在当前线程的ThreadLocal变量resources中设置key-value（key=DataSource对象，value=ConnectionHolder）",[94,1450,1452],{"id":1451},"_22commit提交事务","2.2、commit提交事务",[27,1454,1455],{},[30,1456,1457],{},"AbstractPlatformTransactionManager.commit",[34,1459,1461],{"className":36,"code":1460,"language":38,"meta":39,"style":39},"public final void commit(TransactionStatus status) throws TransactionException {  \n    \u002F\u002F如果事务已完成，抛出异常  \n    if (status.isCompleted()) {  \n       throw new IllegalTransactionStateException(  \n             \"Transaction is already completed - do not call commit or rollback more than once per transaction\");  \n    }  \n  \n    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;  \n    \u002F\u002F事务标记为回滚  \n    if (defStatus.isLocalRollbackOnly()) {  \n       if (defStatus.isDebug()) {  \n          logger.debug(\"Transactional code has requested rollback\");  \n       }  \n       \u002F\u002F执行回滚  \n       processRollback(defStatus, false);  \n       return;  \n    }  \n  \n    \u002F\u002F不需要全局回滚时提交 && 全局回滚  \n    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {  \n       if (defStatus.isDebug()) {  \n          logger.debug(\"Global transaction is marked as rollback-only but transactional code requested commit\");  \n       }  \n       processRollback(defStatus, true);  \n       return;  \n    }  \n  \n    \u002F\u002F执行事务提交  \n    processCommit(defStatus);  \n}\n",[41,1462,1463,1468,1473,1478,1482,1487,1491,1495,1500,1505,1510,1515,1520,1524,1529,1534,1539,1543,1547,1552,1557,1561,1566,1570,1575,1579,1583,1587,1592,1597],{"__ignoreMap":39},[44,1464,1465],{"class":46,"line":47},[44,1466,1467],{},"public final void commit(TransactionStatus status) throws TransactionException {  \n",[44,1469,1470],{"class":46,"line":53},[44,1471,1472],{},"    \u002F\u002F如果事务已完成，抛出异常  \n",[44,1474,1475],{"class":46,"line":59},[44,1476,1477],{},"    if (status.isCompleted()) {  \n",[44,1479,1480],{"class":46,"line":65},[44,1481,253],{},[44,1483,1484],{"class":46,"line":71},[44,1485,1486],{},"             \"Transaction is already completed - do not call commit or rollback more than once per transaction\");  \n",[44,1488,1489],{"class":46,"line":135},[44,1490,196],{},[44,1492,1493],{"class":46,"line":141},[44,1494,127],{},[44,1496,1497],{"class":46,"line":146},[44,1498,1499],{},"    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;  \n",[44,1501,1502],{"class":46,"line":152},[44,1503,1504],{},"    \u002F\u002F事务标记为回滚  \n",[44,1506,1507],{"class":46,"line":158},[44,1508,1509],{},"    if (defStatus.isLocalRollbackOnly()) {  \n",[44,1511,1512],{"class":46,"line":164},[44,1513,1514],{},"       if (defStatus.isDebug()) {  \n",[44,1516,1517],{"class":46,"line":169},[44,1518,1519],{},"          logger.debug(\"Transactional code has requested rollback\");  \n",[44,1521,1522],{"class":46,"line":175},[44,1523,312],{},[44,1525,1526],{"class":46,"line":181},[44,1527,1528],{},"       \u002F\u002F执行回滚  \n",[44,1530,1531],{"class":46,"line":187},[44,1532,1533],{},"       processRollback(defStatus, false);  \n",[44,1535,1536],{"class":46,"line":193},[44,1537,1538],{},"       return;  \n",[44,1540,1541],{"class":46,"line":199},[44,1542,196],{},[44,1544,1545],{"class":46,"line":204},[44,1546,127],{},[44,1548,1549],{"class":46,"line":210},[44,1550,1551],{},"    \u002F\u002F不需要全局回滚时提交 && 全局回滚  \n",[44,1553,1554],{"class":46,"line":216},[44,1555,1556],{},"    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {  \n",[44,1558,1559],{"class":46,"line":222},[44,1560,1514],{},[44,1562,1563],{"class":46,"line":227},[44,1564,1565],{},"          logger.debug(\"Global transaction is marked as rollback-only but transactional code requested commit\");  \n",[44,1567,1568],{"class":46,"line":232},[44,1569,312],{},[44,1571,1572],{"class":46,"line":238},[44,1573,1574],{},"       processRollback(defStatus, true);  \n",[44,1576,1577],{"class":46,"line":244},[44,1578,1538],{},[44,1580,1581],{"class":46,"line":250},[44,1582,196],{},[44,1584,1585],{"class":46,"line":256},[44,1586,127],{},[44,1588,1589],{"class":46,"line":262},[44,1590,1591],{},"    \u002F\u002F执行事务提交  \n",[44,1593,1594],{"class":46,"line":267},[44,1595,1596],{},"    processCommit(defStatus);  \n",[44,1598,1599],{"class":46,"line":273},[44,1600,74],{},[27,1602,1603],{},[30,1604,1605],{},"AbstractPlatformTransactionManager.processCommit",[34,1607,1609],{"className":36,"code":1608,"language":38,"meta":39,"style":39},"private void processCommit(DefaultTransactionStatus status) throws TransactionException {  \n    try {  \n       boolean beforeCompletionInvoked = false;  \n  \n       try {  \n          boolean unexpectedRollback = false;  \n          \u002F\u002F3个前置操作  \n          prepareForCommit(status);  \n          triggerBeforeCommit(status);  \n          triggerBeforeCompletion(status);  \n          beforeCompletionInvoked = true;  \n  \n          \u002F\u002F有保存点，即嵌套事务  \n          if (status.hasSavepoint()) {  \n             if (status.isDebug()) {  \n                logger.debug(\"Releasing transaction savepoint\");  \n             }  \n             unexpectedRollback = status.isGlobalRollbackOnly();  \n             \u002F\u002F释放保存点  \n             status.releaseHeldSavepoint();  \n          }  \n          \u002F\u002F新事务  \n          else if (status.isNewTransaction()) {  \n             if (status.isDebug()) {  \n                logger.debug(\"Initiating transaction commit\");  \n             }  \n             unexpectedRollback = status.isGlobalRollbackOnly();  \n             \u002F\u002F执行提交  \n             doCommit(status);  \n          }  \n          \u002F\u002F全局回滚失败  \n          else if (isFailEarlyOnGlobalRollbackOnly()) {  \n             unexpectedRollback = status.isGlobalRollbackOnly();  \n          }  \n  \n          \u002F\u002F Throw UnexpectedRollbackException if we have a global rollback-only  \n          \u002F\u002F marker but still didn't get a corresponding exception from commit.          if (unexpectedRollback) {  \n             throw new UnexpectedRollbackException(  \n                   \"Transaction silently rolled back because it has been marked as rollback-only\");  \n          }  \n       }  \n       catch (UnexpectedRollbackException ex) {  \n          \u002F\u002F can only be caused by doCommit  \n          \u002F\u002F触发完成后事务同步，状态为回滚  \n          triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);  \n          throw ex;  \n       }  \n       catch (TransactionException ex) {  \n          \u002F\u002F can only be caused by doCommit  \n          \u002F\u002F提交失败回滚  \n          if (isRollbackOnCommitFailure()) {  \n             doRollbackOnCommitException(status, ex);  \n          }  \n          else {  \n             \u002F\u002F触发完成后回调，事务同步状态为未知  \n             triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);  \n          }  \n          throw ex;  \n       }  \n       catch (RuntimeException | Error ex) {  \n          \u002F\u002F如果3个前置步骤没有执行完，调用前置最后一步操作  \n          if (!beforeCompletionInvoked) {  \n             triggerBeforeCompletion(status);  \n          }  \n          doRollbackOnCommitException(status, ex);  \n          throw ex;  \n       }  \n  \n       \u002F\u002F Trigger afterCommit callbacks, with an exception thrown there  \n       \u002F\u002F propagated to callers but the transaction still considered as committed.       try {  \n          triggerAfterCommit(status);  \n       }  \n       finally {  \n          triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);  \n       }  \n  \n    }  \n    finally {  \n       cleanupAfterCompletion(status);  \n    }  \n}\n",[41,1610,1611,1616,1620,1625,1629,1633,1638,1643,1648,1653,1658,1663,1667,1672,1677,1682,1687,1692,1697,1702,1707,1711,1716,1721,1725,1730,1734,1738,1743,1748,1752,1757,1762,1766,1770,1774,1779,1784,1789,1794,1798,1802,1807,1812,1817,1822,1826,1830,1835,1839,1844,1849,1854,1858,1863,1868,1873,1877,1881,1885,1889,1894,1899,1904,1909,1915,1920,1925,1930,1936,1942,1948,1953,1959,1965,1970,1975,1980,1986,1992,1997],{"__ignoreMap":39},[44,1612,1613],{"class":46,"line":47},[44,1614,1615],{},"private void processCommit(DefaultTransactionStatus status) throws TransactionException {  \n",[44,1617,1618],{"class":46,"line":53},[44,1619,1171],{},[44,1621,1622],{"class":46,"line":59},[44,1623,1624],{},"       boolean beforeCompletionInvoked = false;  \n",[44,1626,1627],{"class":46,"line":65},[44,1628,127],{},[44,1630,1631],{"class":46,"line":71},[44,1632,318],{},[44,1634,1635],{"class":46,"line":135},[44,1636,1637],{},"          boolean unexpectedRollback = false;  \n",[44,1639,1640],{"class":46,"line":141},[44,1641,1642],{},"          \u002F\u002F3个前置操作  \n",[44,1644,1645],{"class":46,"line":146},[44,1646,1647],{},"          prepareForCommit(status);  \n",[44,1649,1650],{"class":46,"line":152},[44,1651,1652],{},"          triggerBeforeCommit(status);  \n",[44,1654,1655],{"class":46,"line":158},[44,1656,1657],{},"          triggerBeforeCompletion(status);  \n",[44,1659,1660],{"class":46,"line":164},[44,1661,1662],{},"          beforeCompletionInvoked = true;  \n",[44,1664,1665],{"class":46,"line":169},[44,1666,127],{},[44,1668,1669],{"class":46,"line":175},[44,1670,1671],{},"          \u002F\u002F有保存点，即嵌套事务  \n",[44,1673,1674],{"class":46,"line":181},[44,1675,1676],{},"          if (status.hasSavepoint()) {  \n",[44,1678,1679],{"class":46,"line":187},[44,1680,1681],{},"             if (status.isDebug()) {  \n",[44,1683,1684],{"class":46,"line":193},[44,1685,1686],{},"                logger.debug(\"Releasing transaction savepoint\");  \n",[44,1688,1689],{"class":46,"line":199},[44,1690,1691],{},"             }  \n",[44,1693,1694],{"class":46,"line":204},[44,1695,1696],{},"             unexpectedRollback = status.isGlobalRollbackOnly();  \n",[44,1698,1699],{"class":46,"line":210},[44,1700,1701],{},"             \u002F\u002F释放保存点  \n",[44,1703,1704],{"class":46,"line":216},[44,1705,1706],{},"             status.releaseHeldSavepoint();  \n",[44,1708,1709],{"class":46,"line":222},[44,1710,804],{},[44,1712,1713],{"class":46,"line":227},[44,1714,1715],{},"          \u002F\u002F新事务  \n",[44,1717,1718],{"class":46,"line":232},[44,1719,1720],{},"          else if (status.isNewTransaction()) {  \n",[44,1722,1723],{"class":46,"line":238},[44,1724,1681],{},[44,1726,1727],{"class":46,"line":244},[44,1728,1729],{},"                logger.debug(\"Initiating transaction commit\");  \n",[44,1731,1732],{"class":46,"line":250},[44,1733,1691],{},[44,1735,1736],{"class":46,"line":256},[44,1737,1696],{},[44,1739,1740],{"class":46,"line":262},[44,1741,1742],{},"             \u002F\u002F执行提交  \n",[44,1744,1745],{"class":46,"line":267},[44,1746,1747],{},"             doCommit(status);  \n",[44,1749,1750],{"class":46,"line":273},[44,1751,804],{},[44,1753,1754],{"class":46,"line":279},[44,1755,1756],{},"          \u002F\u002F全局回滚失败  \n",[44,1758,1759],{"class":46,"line":285},[44,1760,1761],{},"          else if (isFailEarlyOnGlobalRollbackOnly()) {  \n",[44,1763,1764],{"class":46,"line":291},[44,1765,1696],{},[44,1767,1768],{"class":46,"line":297},[44,1769,804],{},[44,1771,1772],{"class":46,"line":303},[44,1773,127],{},[44,1775,1776],{"class":46,"line":309},[44,1777,1778],{},"          \u002F\u002F Throw UnexpectedRollbackException if we have a global rollback-only  \n",[44,1780,1781],{"class":46,"line":315},[44,1782,1783],{},"          \u002F\u002F marker but still didn't get a corresponding exception from commit.          if (unexpectedRollback) {  \n",[44,1785,1786],{"class":46,"line":321},[44,1787,1788],{},"             throw new UnexpectedRollbackException(  \n",[44,1790,1791],{"class":46,"line":327},[44,1792,1793],{},"                   \"Transaction silently rolled back because it has been marked as rollback-only\");  \n",[44,1795,1796],{"class":46,"line":332},[44,1797,804],{},[44,1799,1800],{"class":46,"line":338},[44,1801,312],{},[44,1803,1804],{"class":46,"line":344},[44,1805,1806],{},"       catch (UnexpectedRollbackException ex) {  \n",[44,1808,1809],{"class":46,"line":350},[44,1810,1811],{},"          \u002F\u002F can only be caused by doCommit  \n",[44,1813,1814],{"class":46,"line":355},[44,1815,1816],{},"          \u002F\u002F触发完成后事务同步，状态为回滚  \n",[44,1818,1819],{"class":46,"line":360},[44,1820,1821],{},"          triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);  \n",[44,1823,1824],{"class":46,"line":366},[44,1825,347],{},[44,1827,1828],{"class":46,"line":372},[44,1829,312],{},[44,1831,1832],{"class":46,"line":378},[44,1833,1834],{},"       catch (TransactionException ex) {  \n",[44,1836,1837],{"class":46,"line":384},[44,1838,1811],{},[44,1840,1841],{"class":46,"line":390},[44,1842,1843],{},"          \u002F\u002F提交失败回滚  \n",[44,1845,1846],{"class":46,"line":396},[44,1847,1848],{},"          if (isRollbackOnCommitFailure()) {  \n",[44,1850,1851],{"class":46,"line":402},[44,1852,1853],{},"             doRollbackOnCommitException(status, ex);  \n",[44,1855,1856],{"class":46,"line":407},[44,1857,804],{},[44,1859,1860],{"class":46,"line":413},[44,1861,1862],{},"          else {  \n",[44,1864,1865],{"class":46,"line":419},[44,1866,1867],{},"             \u002F\u002F触发完成后回调，事务同步状态为未知  \n",[44,1869,1870],{"class":46,"line":424},[44,1871,1872],{},"             triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);  \n",[44,1874,1875],{"class":46,"line":705},[44,1876,804],{},[44,1878,1879],{"class":46,"line":710},[44,1880,347],{},[44,1882,1883],{"class":46,"line":716},[44,1884,312],{},[44,1886,1887],{"class":46,"line":722},[44,1888,335],{},[44,1890,1891],{"class":46,"line":731},[44,1892,1893],{},"          \u002F\u002F如果3个前置步骤没有执行完，调用前置最后一步操作  \n",[44,1895,1896],{"class":46,"line":737},[44,1897,1898],{},"          if (!beforeCompletionInvoked) {  \n",[44,1900,1901],{"class":46,"line":742},[44,1902,1903],{},"             triggerBeforeCompletion(status);  \n",[44,1905,1907],{"class":46,"line":1906},64,[44,1908,804],{},[44,1910,1912],{"class":46,"line":1911},65,[44,1913,1914],{},"          doRollbackOnCommitException(status, ex);  \n",[44,1916,1918],{"class":46,"line":1917},66,[44,1919,347],{},[44,1921,1923],{"class":46,"line":1922},67,[44,1924,312],{},[44,1926,1928],{"class":46,"line":1927},68,[44,1929,127],{},[44,1931,1933],{"class":46,"line":1932},69,[44,1934,1935],{},"       \u002F\u002F Trigger afterCommit callbacks, with an exception thrown there  \n",[44,1937,1939],{"class":46,"line":1938},70,[44,1940,1941],{},"       \u002F\u002F propagated to callers but the transaction still considered as committed.       try {  \n",[44,1943,1945],{"class":46,"line":1944},71,[44,1946,1947],{},"          triggerAfterCommit(status);  \n",[44,1949,1951],{"class":46,"line":1950},72,[44,1952,312],{},[44,1954,1956],{"class":46,"line":1955},73,[44,1957,1958],{},"       finally {  \n",[44,1960,1962],{"class":46,"line":1961},74,[44,1963,1964],{},"          triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);  \n",[44,1966,1968],{"class":46,"line":1967},75,[44,1969,312],{},[44,1971,1973],{"class":46,"line":1972},76,[44,1974,127],{},[44,1976,1978],{"class":46,"line":1977},77,[44,1979,196],{},[44,1981,1983],{"class":46,"line":1982},78,[44,1984,1985],{},"    finally {  \n",[44,1987,1989],{"class":46,"line":1988},79,[44,1990,1991],{},"       cleanupAfterCompletion(status);  \n",[44,1993,1995],{"class":46,"line":1994},80,[44,1996,196],{},[44,1998,2000],{"class":46,"line":1999},81,[44,2001,74],{},[94,2003,2005],{"id":2004},"_23rollback回滚事务","2.3、rollback回滚事务",[27,2007,2008],{},[30,2009,2010],{},"AbstractPlatformTransactionManager.processRollback",[34,2012,2014],{"className":36,"code":2013,"language":38,"meta":39,"style":39},"private void processRollback(DefaultTransactionStatus status, boolean unexpected) {  \n    try {  \n       boolean unexpectedRollback = unexpected;  \n  \n       try {  \n          \u002F\u002F触发前置操作：遍历事务同步信息触发beforeCompletion  \n          triggerBeforeCompletion(status);  \n  \n          \u002F\u002F有保存点(即嵌套式事务)，回滚到保存点  \n          if (status.hasSavepoint()) {  \n             if (status.isDebug()) {  \n                logger.debug(\"Rolling back transaction to savepoint\");  \n             }  \n             status.rollbackToHeldSavepoint();  \n          }  \n          else if (status.isNewTransaction()) {  \n             if (status.isDebug()) {  \n                logger.debug(\"Initiating transaction rollback\");  \n             }  \n             \u002F\u002F执行回滚  \n             doRollback(status);  \n          }  \n          else {  \n             \u002F\u002F非新事务&无保存点，加入当前事务  \n             \u002F\u002F Participating in larger transaction  \n             if (status.hasTransaction()) {  \n                if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {  \n                   if (status.isDebug()) {  \n                      logger.debug(\"Participating transaction failed - marking existing transaction as rollback-only\");  \n                   }  \n                   doSetRollbackOnly(status);  \n                }  \n                else {  \n                   if (status.isDebug()) {  \n                      logger.debug(\"Participating transaction failed - letting transaction originator decide on rollback\");  \n                   }  \n                }  \n             }  \n             else {  \n                logger.debug(\"Should roll back transaction but cannot - no transaction available\");  \n             }  \n             \u002F\u002F Unexpected rollback only matters here if we're asked to fail early  \n             if (!isFailEarlyOnGlobalRollbackOnly()) {  \n                unexpectedRollback = false;  \n             }  \n          }  \n       }  \n       catch (RuntimeException | Error ex) {  \n          triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);  \n          throw ex;  \n       }  \n  \n       \u002F\u002F遍历事务同步信息执行invokeAfterCompletion  \n       triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);  \n  \n       \u002F\u002F Raise UnexpectedRollbackException if we had a global rollback-only marker  \n       if (unexpectedRollback) {  \n          throw new UnexpectedRollbackException(  \n                \"Transaction rolled back because it has been marked as rollback-only\");  \n       }  \n    }  \n    finally {  \n       \u002F\u002F完成后清理  \n       cleanupAfterCompletion(status);  \n    }  \n}\n",[41,2015,2016,2021,2025,2030,2034,2038,2043,2047,2051,2056,2060,2064,2069,2073,2078,2082,2086,2090,2095,2099,2104,2109,2113,2117,2122,2127,2132,2137,2142,2147,2152,2157,2162,2167,2171,2176,2180,2184,2188,2193,2198,2202,2207,2212,2217,2221,2225,2229,2233,2238,2242,2246,2250,2255,2260,2264,2269,2274,2279,2284,2288,2292,2296,2301,2305,2309],{"__ignoreMap":39},[44,2017,2018],{"class":46,"line":47},[44,2019,2020],{},"private void processRollback(DefaultTransactionStatus status, boolean unexpected) {  \n",[44,2022,2023],{"class":46,"line":53},[44,2024,1171],{},[44,2026,2027],{"class":46,"line":59},[44,2028,2029],{},"       boolean unexpectedRollback = unexpected;  \n",[44,2031,2032],{"class":46,"line":65},[44,2033,127],{},[44,2035,2036],{"class":46,"line":71},[44,2037,318],{},[44,2039,2040],{"class":46,"line":135},[44,2041,2042],{},"          \u002F\u002F触发前置操作：遍历事务同步信息触发beforeCompletion  \n",[44,2044,2045],{"class":46,"line":141},[44,2046,1657],{},[44,2048,2049],{"class":46,"line":146},[44,2050,127],{},[44,2052,2053],{"class":46,"line":152},[44,2054,2055],{},"          \u002F\u002F有保存点(即嵌套式事务)，回滚到保存点  \n",[44,2057,2058],{"class":46,"line":158},[44,2059,1676],{},[44,2061,2062],{"class":46,"line":164},[44,2063,1681],{},[44,2065,2066],{"class":46,"line":169},[44,2067,2068],{},"                logger.debug(\"Rolling back transaction to savepoint\");  \n",[44,2070,2071],{"class":46,"line":175},[44,2072,1691],{},[44,2074,2075],{"class":46,"line":181},[44,2076,2077],{},"             status.rollbackToHeldSavepoint();  \n",[44,2079,2080],{"class":46,"line":187},[44,2081,804],{},[44,2083,2084],{"class":46,"line":193},[44,2085,1720],{},[44,2087,2088],{"class":46,"line":199},[44,2089,1681],{},[44,2091,2092],{"class":46,"line":204},[44,2093,2094],{},"                logger.debug(\"Initiating transaction rollback\");  \n",[44,2096,2097],{"class":46,"line":210},[44,2098,1691],{},[44,2100,2101],{"class":46,"line":216},[44,2102,2103],{},"             \u002F\u002F执行回滚  \n",[44,2105,2106],{"class":46,"line":222},[44,2107,2108],{},"             doRollback(status);  \n",[44,2110,2111],{"class":46,"line":227},[44,2112,804],{},[44,2114,2115],{"class":46,"line":232},[44,2116,1862],{},[44,2118,2119],{"class":46,"line":238},[44,2120,2121],{},"             \u002F\u002F非新事务&无保存点，加入当前事务  \n",[44,2123,2124],{"class":46,"line":244},[44,2125,2126],{},"             \u002F\u002F Participating in larger transaction  \n",[44,2128,2129],{"class":46,"line":250},[44,2130,2131],{},"             if (status.hasTransaction()) {  \n",[44,2133,2134],{"class":46,"line":256},[44,2135,2136],{},"                if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {  \n",[44,2138,2139],{"class":46,"line":262},[44,2140,2141],{},"                   if (status.isDebug()) {  \n",[44,2143,2144],{"class":46,"line":267},[44,2145,2146],{},"                      logger.debug(\"Participating transaction failed - marking existing transaction as rollback-only\");  \n",[44,2148,2149],{"class":46,"line":273},[44,2150,2151],{},"                   }  \n",[44,2153,2154],{"class":46,"line":279},[44,2155,2156],{},"                   doSetRollbackOnly(status);  \n",[44,2158,2159],{"class":46,"line":285},[44,2160,2161],{},"                }  \n",[44,2163,2164],{"class":46,"line":291},[44,2165,2166],{},"                else {  \n",[44,2168,2169],{"class":46,"line":297},[44,2170,2141],{},[44,2172,2173],{"class":46,"line":303},[44,2174,2175],{},"                      logger.debug(\"Participating transaction failed - letting transaction originator decide on rollback\");  \n",[44,2177,2178],{"class":46,"line":309},[44,2179,2151],{},[44,2181,2182],{"class":46,"line":315},[44,2183,2161],{},[44,2185,2186],{"class":46,"line":321},[44,2187,1691],{},[44,2189,2190],{"class":46,"line":327},[44,2191,2192],{},"             else {  \n",[44,2194,2195],{"class":46,"line":332},[44,2196,2197],{},"                logger.debug(\"Should roll back transaction but cannot - no transaction available\");  \n",[44,2199,2200],{"class":46,"line":338},[44,2201,1691],{},[44,2203,2204],{"class":46,"line":344},[44,2205,2206],{},"             \u002F\u002F Unexpected rollback only matters here if we're asked to fail early  \n",[44,2208,2209],{"class":46,"line":350},[44,2210,2211],{},"             if (!isFailEarlyOnGlobalRollbackOnly()) {  \n",[44,2213,2214],{"class":46,"line":355},[44,2215,2216],{},"                unexpectedRollback = false;  \n",[44,2218,2219],{"class":46,"line":360},[44,2220,1691],{},[44,2222,2223],{"class":46,"line":366},[44,2224,804],{},[44,2226,2227],{"class":46,"line":372},[44,2228,312],{},[44,2230,2231],{"class":46,"line":378},[44,2232,335],{},[44,2234,2235],{"class":46,"line":384},[44,2236,2237],{},"          triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);  \n",[44,2239,2240],{"class":46,"line":390},[44,2241,347],{},[44,2243,2244],{"class":46,"line":396},[44,2245,312],{},[44,2247,2248],{"class":46,"line":402},[44,2249,127],{},[44,2251,2252],{"class":46,"line":407},[44,2253,2254],{},"       \u002F\u002F遍历事务同步信息执行invokeAfterCompletion  \n",[44,2256,2257],{"class":46,"line":413},[44,2258,2259],{},"       triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);  \n",[44,2261,2262],{"class":46,"line":419},[44,2263,127],{},[44,2265,2266],{"class":46,"line":424},[44,2267,2268],{},"       \u002F\u002F Raise UnexpectedRollbackException if we had a global rollback-only marker  \n",[44,2270,2271],{"class":46,"line":705},[44,2272,2273],{},"       if (unexpectedRollback) {  \n",[44,2275,2276],{"class":46,"line":710},[44,2277,2278],{},"          throw new UnexpectedRollbackException(  \n",[44,2280,2281],{"class":46,"line":716},[44,2282,2283],{},"                \"Transaction rolled back because it has been marked as rollback-only\");  \n",[44,2285,2286],{"class":46,"line":722},[44,2287,312],{},[44,2289,2290],{"class":46,"line":731},[44,2291,196],{},[44,2293,2294],{"class":46,"line":737},[44,2295,1985],{},[44,2297,2298],{"class":46,"line":742},[44,2299,2300],{},"       \u002F\u002F完成后清理  \n",[44,2302,2303],{"class":46,"line":1906},[44,2304,1991],{},[44,2306,2307],{"class":46,"line":1911},[44,2308,196],{},[44,2310,2311],{"class":46,"line":1917},[44,2312,74],{},[2314,2315,2316],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":39,"searchDepth":53,"depth":53,"links":2318},[2319,2320,2321],{"id":96,"depth":53,"text":97},{"id":1451,"depth":53,"text":1452},{"id":2004,"depth":53,"text":2005},[2323],"spring",true,"2021-11-07","本文主要介绍spring事务（JDBC单数据库事务管理）的核心源码实现 1、核心类介绍 我们可以先看一下核心类图。 PlatformTransactionManager 底层接口，定义事务方法 AbstractPlatformTransactionManager 抽象类，实现PlatformTran",false,"md","spring-transaction-core-implementation",{},"\u002Fblog\u002F2021\u002F11\u002F07\u002Fspring-transaction-core-implementation",{"title":5,"description":2326},"blog\u002F2021\u002F11\u002F07\u002Fspring-transaction-core-implementation",[2323],null,"SGwvkzwn5OpNgFAK1CM9XqXQrIQp-FUaBLpTOUBL1ZU",1783807996347]