spring事務(wù)的propagation傳播屬性示例詳解
序
本文主要研究一下spring事務(wù)的propagation
Propagation
org/springframework/transaction/annotation/Propagation.java
/** * Enumeration that represents transaction propagation behaviors for use * with the {@link Transactional} annotation, corresponding to the * {@link TransactionDefinition} interface. * * @author Colin Sampaleanu * @author Juergen Hoeller * @since 1.2 */ public enum Propagation { /** * Support a current transaction, create a new one if none exists. * Analogous to EJB transaction attribute of the same name. * <p>This is the default setting of a transaction annotation. */ REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), /** * Support a current transaction, execute non-transactionally if none exists. * Analogous to EJB transaction attribute of the same name. * <p>Note: For transaction managers with transaction synchronization, * {@code SUPPORTS} is slightly different from no transaction at all, * as it defines a transaction scope that synchronization will apply for. * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) * will be shared for the entire specified scope. Note that this depends on * the actual synchronization configuration of the transaction manager. * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization */ SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), /** * Support a current transaction, throw an exception if none exists. * Analogous to EJB transaction attribute of the same name. */ MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), /** * Create a new transaction, and suspend the current transaction if one exists. * Analogous to the EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code javax.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), /** * Execute non-transactionally, suspend the current transaction if one exists. * Analogous to EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code javax.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), /** * Execute non-transactionally, throw an exception if a transaction exists. * Analogous to EJB transaction attribute of the same name. */ NEVER(TransactionDefinition.PROPAGATION_NEVER), /** * Execute within a nested transaction if a current transaction exists, * behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB. * <p>Note: Actual creation of a nested transaction will only work on specific * transaction managers. Out of the box, this only applies to the JDBC * DataSourceTransactionManager. Some JTA providers might support nested * transactions as well. * @see org.springframework.jdbc.datasource.DataSourceTransactionManager */ NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; } }
spring事務(wù)定義了Propagation枚舉,主要有REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED
AbstractPlatformTransactionManager
org/springframework/transaction/support/AbstractPlatformTransactionManager.java
/** * Create a TransactionStatus for an existing transaction. */ private TransactionStatus handleExistingTransaction( TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException { if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) { throw new IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation 'never'"); } 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); } 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 | Error beginEx) { resumeAfterBeginException(transaction, suspendedResources, beginEx); throw beginEx; } } 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); }
AbstractPlatformTransactionManager的handleExistingTransaction方法對(duì)各個(gè)傳播級(jí)別進(jìn)行了處理,比如針對(duì)PROPAGATION_REQUIRES_NEW,它會(huì)執(zhí)行suspend當(dāng)前事務(wù),然后newTransactionStatus
小結(jié)
spring事務(wù)提供了各種傳播級(jí)別可以設(shè)置,它主要是為了方便處理事務(wù)嵌套的場(chǎng)景,可以支持里外共用一個(gè)事務(wù),或者里頭新開(kāi)事務(wù)等等,這樣子可以解決里外重復(fù)開(kāi)事務(wù)等問(wèn)題。但是這個(gè)用多了也要注意,在調(diào)用的時(shí)候需要設(shè)置什么傳播級(jí)別。其實(shí)其他語(yǔ)言可能沒(méi)有事務(wù)傳播這一說(shuō),一般就是盡量把代碼寫(xiě)簡(jiǎn)單點(diǎn),少用事務(wù)嵌套。
以上就是spring事務(wù)的propagation傳播屬性示例詳解的詳細(xì)內(nèi)容,更多關(guān)于spring事務(wù)propagation的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Resilience4J通過(guò)yml設(shè)置circuitBreaker的方法
Resilience4j是一個(gè)輕量級(jí)、易于使用的容錯(cuò)庫(kù),其靈感來(lái)自Netflix Hystrix,但專(zhuān)為Java 8和函數(shù)式編程設(shè)計(jì),這篇文章主要介紹了Resilience4J通過(guò)yml設(shè)置circuitBreaker的方法,需要的朋友可以參考下2022-10-10Java、C++中子類(lèi)對(duì)父類(lèi)函數(shù)覆蓋的可訪問(wèn)性縮小的區(qū)別介紹
這篇文章主要給大家介紹了關(guān)于Java、C++中子類(lèi)對(duì)父類(lèi)函數(shù)覆蓋的可訪問(wèn)性縮小的區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01淺談Java中對(duì)類(lèi)的主動(dòng)引用和被動(dòng)引用
這篇文章主要介紹了淺談Java中對(duì)類(lèi)的主動(dòng)引用和被動(dòng)引用,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02深入理解Mybatis中的resultType和resultMap
這篇文章給大家介紹了mybatis中的resultType和resultMap的用法實(shí)例講解,MyBatis中在查詢(xún)進(jìn)行select映射的時(shí)候,返回類(lèi)型可以用resultType,也可以用resultMap,至于兩種用法區(qū)別,通過(guò)本文一起學(xué)習(xí)吧2016-09-09SpringBoot3整合SpringSecurity6快速入門(mén)示例教程
SpringSecurity 是Spring大家族中一名重要成員,是專(zhuān)門(mén)負(fù)責(zé)安全的框架,本文給大家介紹SpringBoot3整合SpringSecurity6快速入門(mén)示例教程,感興趣的朋友一起看看吧2025-04-04Guava范圍類(lèi)Range方法實(shí)例深入解析
這篇文章主要為大家介紹了Guava范圍類(lèi)Range方法實(shí)例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12java保證對(duì)象在內(nèi)存中唯一性的實(shí)現(xiàn)方法
這篇文章主要介紹了java如何保證對(duì)象在內(nèi)存中的唯一性,如果創(chuàng)建多個(gè)對(duì)象的話,可能會(huì)引發(fā)出各種各樣的問(wèn)題,這時(shí),就需要我們保證這個(gè)對(duì)象在內(nèi)存中的唯一性,需要的朋友可以參考下2019-06-06mybatis多層嵌套resultMap及返回自定義參數(shù)詳解
這篇文章主要介紹了mybatis多層嵌套resultMap及返回自定義參數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12