spring事务深入剖析 - JDBC DataSourceTransactionManager 分析
http://blue2048.iteye.com/blog/2176676
首先介绍下DataSourceTransactionObject这个类,它是DataSourceTransactionManager的事务句柄,用于和AbstractPlatformTransactionManager接口方法之间的交互数据传递
下面介绍DataSourceTransactionManager各个方法,解析见注释
1. doGetTransaction
- //产生一个DataSourceTransactionObject对象,其中持有ConnectionHolder(从ThreadLocale中拿,可能已经存在这个对象)
- protected Object doGetTransaction() {
- DataSourceTransactionObject txObject = new DataSourceTransactionObject();
- txObject.setSavepointAllowed(isNestedTransactionAllowed());
- ConnectionHolder conHolder =
- (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
- txObject.setConnectionHolder(conHolder, false);
- return txObject;
- }
2. isExistingTransaction
- //从DataSourceTransactionObject取出ConnectionHolder对象,判断connection上是否已经开启过事务protected boolean isExistingTransaction(Object transaction) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
- return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
- }
3. doBegin
a. 从DataSourceTransactionObject拿出ConnectionHolder
b. 从ConnectionHolder拿Connection,设置事务的隔离级别,并开启事务
c. 将ConnectionHolder绑定到当前Connection上,以被嵌套的事务获取(因为JDBC连接池是根据线程绑定Connection的,所有一次嵌套事务中,使用的是同一个Connection)
- protected void doBegin(Object transaction, TransactionDefinition definition) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
- Connection con = null;
- try {
- if (txObject.getConnectionHolder() == null ||
- txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
- Connection newCon = this.dataSource.getConnection();
- if (logger.isDebugEnabled()) {
- logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
- }
- txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
- }
- txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
- con = txObject.getConnectionHolder().getConnection();
- Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
- txObject.setPreviousIsolationLevel(previousIsolationLevel);
- // 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);
- int timeout = determineTimeout(definition);
- if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
- txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
- }
- // Bind the session holder to the thread.
- if (txObject.isNewConnectionHolder()) {
- TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
- }
- }
- catch (Exception ex) {
- DataSourceUtils.releaseConnection(con, this.dataSource);
- throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
- }
- }
4. doSuspend
- //清除DataSourceTransactionObject和ThreadLocal中存储的ConnectionHolder对象,外部保存ConnectionHolder对象,以备恢复使用
- protected Object doSuspend(Object transaction) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
- txObject.setConnectionHolder(null);
- ConnectionHolder conHolder = (ConnectionHolder)
- TransactionSynchronizationManager.unbindResource(this.dataSource);
- return conHolder;
- }
5. doResume
- //外部传入ConnectionHolder对象,恢复到ThreadLocal中去
- protected void doResume(Object transaction, Object suspendedResources) {
- ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;
- TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);
- }
6. doCommit
- protected void doCommit(DefaultTransactionStatus status) {
- 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);
- }
- }
7. doRollback
- protected 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);
- }
- }
8. doSetRollbackOnly
- protected void doSetRollbackOnly(DefaultTransactionStatus status) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
- if (status.isDebug()) {
- logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +
- "] rollback-only");
- }
- txObject.setRollbackOnly();
- }
9. doCleanupAfterCompletion
a. 从ThreadLocal中将ConnectionHolder清除
b. 回复Connecton之前的AutoCommit和IsolationLevel属性
c. 释放connection
d. 清除ConnectHolder相应的对象属性
- protected void doCleanupAfterCompletion(Object transaction) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
- // Remove the connection holder from the thread, if exposed.
- if (txObject.isNewConnectionHolder()) {
- TransactionSynchronizationManager.unbindResource(this.dataSource);
- }
- // Reset connection.
- Connection con = txObject.getConnectionHolder().getConnection();
- try {
- if (txObject.isMustRestoreAutoCommit()) {
- con.setAutoCommit(true);
- }
- DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
- }
- 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();
- }

浙公网安备 33010602011771号