日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring Boot Transaction 源码解析(二)

發(fā)布時(shí)間:2024/4/13 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot Transaction 源码解析(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

DataSourceTransactionManager

doGetTransaction

?isExistingTransaction

doBegin?

?doCommit

doSuspend

doRollback

doCleanupAfterCompletion

DataSourceUtils

ConnectionSynchronization

?suspend


JDBC事務(wù)時(shí)Spring 事務(wù)的具體實(shí)現(xiàn)。

DataSourceTransactionManager

public class DataSourceTransactionManager extends AbstractPlatformTransactionManagerimplements ResourceTransactionManager, InitializingBean {//數(shù)據(jù)庫(kù)DataSourceprivate DataSource dataSource;private boolean enforceReadOnly = false; }

doGetTransaction

構(gòu)造DataSourceTransactionObject,存儲(chǔ)ConnectionHolder

@Overrideprotected Object doGetTransaction() {DataSourceTransactionObject txObject = new DataSourceTransactionObject();txObject.setSavepointAllowed(isNestedTransactionAllowed()); //通過(guò)DataSource獲取ConnectionHolder ConnectionHolder conHolder =(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource()); //DataSourceTransactionObject設(shè)置ConnectionHolder txObject.setConnectionHolder(conHolder, false);return txObject;}

?isExistingTransaction

如果存在getConnectionHolder,并且有活躍事務(wù),則表示已存在事務(wù)。

@Overrideprotected boolean isExistingTransaction(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());}

doBegin?

主要功能就是保存Connection,設(shè)置事務(wù)狀態(tài)。

@Overrideprotected void doBegin(Object transaction, TransactionDefinition definition) {//獲取事務(wù)對(duì)象。DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = null;try {//如果沒(méi)有ConnectionHolder,則構(gòu)造一個(gè)。if (!txObject.hasConnectionHolder() ||txObject.getConnectionHolder().isSynchronizedWithTransaction()) {Connection newCon = obtainDataSource().getConnection();if (logger.isDebugEnabled()) {logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");}txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}txObject.getConnectionHolder().setSynchronizedWithTransaction(true);//從事務(wù)對(duì)象獲取Connectioncon = txObject.getConnectionHolder().getConnection();//事務(wù)準(zhǔn)備,返回隔離級(jí)別,并設(shè)置到當(dāng)前事務(wù)對(duì)象。Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);txObject.setPreviousIsolationLevel(previousIsolationLevel);txObject.setReadOnly(definition.isReadOnly());// 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).//是否自動(dòng)提交。如果是自動(dòng)提交,則改為手動(dòng)提交。if (con.getAutoCommit()) {txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug("Switching JDBC Connection [" + con + "] to manual commit");}con.setAutoCommit(false);}//準(zhǔn)備提交。prepareTransactionalConnection(con, definition);//激活當(dāng)前事務(wù)。txObject.getConnectionHolder().setTransactionActive(true);//設(shè)置超時(shí)。int timeout = determineTimeout(definition);if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// 如果是新建的,則綁定到當(dāng)前線程。if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch (Throwable ex) {if (txObject.isNewConnectionHolder()) {DataSourceUtils.releaseConnection(con, obtainDataSource());txObject.setConnectionHolder(null, false);}throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);}}

?doCommit

通過(guò)事務(wù)的Connection,調(diào)用commit方法,提交事務(wù)。

@Overrideprotected void doCommit(DefaultTransactionStatus status) { //從事務(wù)對(duì)象中獲取Connection,調(diào)用Connection的提交。DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();Connection con = txObject.getConnectionHolder().getConnection();if (status.isDebug()) {logger.debug("Committing JDBC transaction on Connection [" + con + "]");}try {con.commit();}catch (SQLException ex) {throw new TransactionSystemException("Could not commit JDBC transaction", ex);}}

doSuspend

Connection設(shè)置為null,解綁資源

@Overrideprotected Object doSuspend(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;txObject.setConnectionHolder(null); //當(dāng)前線程解綁資源,return TransactionSynchronizationManager.unbindResource(obtainDataSource());}@Overrideprotected void doResume(@Nullable Object transaction, Object suspendedResources) { //重新綁定資源TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);}

doRollback

調(diào)用Connection.rollback()方法回滾事務(wù)。

@Overrideprotected void doRollback(DefaultTransactionStatus status) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();Connection con = txObject.getConnectionHolder().getConnection();if (status.isDebug()) {logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");}try {con.rollback();}catch (SQLException ex) {throw new TransactionSystemException("Could not roll back JDBC transaction", ex);}}

doCleanupAfterCompletion

如果新事務(wù),解綁資源。恢復(fù)狀態(tài):自動(dòng)提交、connection。

@Overrideprotected void doCleanupAfterCompletion(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;// Remove the connection holder from the thread, if exposed.if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.unbindResource(obtainDataSource());}// Reset connection.Connection con = txObject.getConnectionHolder().getConnection();try {if (txObject.isMustRestoreAutoCommit()) {con.setAutoCommit(true);}DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());}catch (Throwable ex) {logger.debug("Could not reset JDBC Connection after transaction", ex);}if (txObject.isNewConnectionHolder()) {if (logger.isDebugEnabled()) {logger.debug("Releasing JDBC Connection [" + con + "] after transaction");}DataSourceUtils.releaseConnection(con, this.dataSource);}txObject.getConnectionHolder().clear();}

DataSourceUtils

DataSourceUtils,工具類,用于輔助DataSource操作。主要就是Connection相關(guān)操作,

ConnectionSynchronization

用于事務(wù)同步。

private final ConnectionHolder connectionHolder;private final DataSource dataSource;private int order;private boolean holderActive = true;

?suspend

解綁datasource資源,釋放connection。

@Overridepublic void suspend() {if (this.holderActive) {TransactionSynchronizationManager.unbindResource(this.dataSource);if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) {// Release Connection on suspend if the application doesn't keep// a handle to it anymore. We will fetch a fresh Connection if the// application accesses the ConnectionHolder again after resume,// assuming that it will participate in the same transaction.releaseConnection(this.connectionHolder.getConnection(), this.dataSource);this.connectionHolder.setConnection(null);}}} @Overridepublic void resume() {if (this.holderActive) {TransactionSynchronizationManager.bindResource(this.dataSource, this.connectionHolder);}} @Overridepublic void beforeCompletion() {// Release Connection early if the holder is not open anymore// (that is, not used by another resource like a Hibernate Session// that has its own cleanup via transaction synchronization),// to avoid issues with strict JTA implementations that expect// the close call before transaction completion.if (!this.connectionHolder.isOpen()) {TransactionSynchronizationManager.unbindResource(this.dataSource);this.holderActive = false;if (this.connectionHolder.hasConnection()) {releaseConnection(this.connectionHolder.getConnection(), this.dataSource);}}}@Overridepublic void afterCompletion(int status) {// If we haven't closed the Connection in beforeCompletion,// close it now. The holder might have been used for other// cleanup in the meantime, for example by a Hibernate Session.if (this.holderActive) {// The thread-bound ConnectionHolder might not be available anymore,// since afterCompletion might get called from a different thread.TransactionSynchronizationManager.unbindResourceIfPossible(this.dataSource);this.holderActive = false;if (this.connectionHolder.hasConnection()) {releaseConnection(this.connectionHolder.getConnection(), this.dataSource);// Reset the ConnectionHolder: It might remain bound to the thread.this.connectionHolder.setConnection(null);}}this.connectionHolder.reset();}

?

總結(jié)

以上是生活随笔為你收集整理的Spring Boot Transaction 源码解析(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。