Spring事务传播原理及数据库事务操作原理

xml基本配置

<!-- 配置事务通知属性 -->
	<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="login" propagation="NOT_SUPPORTED"/>
			<tx:method name="query*" read-only="true"/>
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
        <aop:aspect ref="dataSource">
            <aop:pointcut id="transactionPointcut" expression="execution(public * com.gupaoedu..*.service..*Service.*(..))" />
        </aop:aspect>
    </aop:config>
package org.springframework.jdbc.datasource;

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
		implements ResourceTransactionManager, InitializingBean {
	
	@Nullable
    private DataSource dataSource;
	
	@Override
	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);
		}
	}

	@Override
	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);
		}
	}
}
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource {
	
	public DruidPooledConnection getConnection() throws SQLException {
        return this.getConnection(this.maxWait);
    }

    public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
        this.init();
        if (this.filters.size() > 0) {
            FilterChainImpl filterChain = new FilterChainImpl(this);
            return filterChain.dataSource_connect(this, maxWaitMillis);
        } else {
            return this.getConnectionDirect(maxWaitMillis);
        }
    }

}
package java.sql;
public interface Connection  extends Wrapper, AutoCloseable {}

package com.mysql.jdbc;
public interface Connection extends java.sql.Connection, ConnectionProperties {}

package com.mysql.jdbc;
public interface MySQLConnection extends Connection, ConnectionProperties {}

package com.mysql.jdbc;
public class ConnectionImpl extends ConnectionPropertiesImpl implements MySQLConnection {

private MysqlIO io;

  /**
   * 执行事务提交方法
   */
public void commit() throws SQLException {
        synchronized(this.getMutex()) {
            this.checkClosed();

            try {
                ......

                this.execSQL((StatementImpl)null, "commit", -1, (Buffer)null, 1003, 1007, false, this.database, (Field[])null, false);
                
            } catch (SQLException var9) {
                
            } finally {
                this.needsPing = this.getReconnectAtTxEnd();
            }

        }
    }

  /**
   * 执行事务回滚方法
   */
private void rollbackNoChecks() throws SQLException {
        if (!this.getUseLocalTransactionState() || !this.versionMeetsMinimum(5, 0, 0) || this.io.inTransactionOnServer()) {
            this.execSQL((StatementImpl)null, "rollback", -1, (Buffer)null, 1003, 1007, false, this.database, (Field[])null, false);
        }
    }

  /**
   * 执行SQL
   */
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata) throws SQLException {
        return this.execSQL(callingStatement, sql, maxRows, packet, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata, false);
    }

  /**
   * 关闭链接
   */
public synchronized void close() throws SQLException {
        if (this.connectionLifecycleInterceptors != null) {
            (new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
                void forEach(Object each) throws SQLException {
                    ((ConnectionLifecycleInterceptor)each).close();
                }
            }).doForAll();
        }

        this.realClose(true, true, false, (Throwable)null);
    }

  /**
   * 创建链接
   */
private void coreConnect(Properties mergedProps) throws SQLException, IOException {
        int newPort = 3306;
        String newHost = "localhost";
        String protocol = mergedProps.getProperty("PROTOCOL");
        ......
        this.port = newPort;
        this.host = newHost;

		// 创建socket
        this.io = new MysqlIO(newHost, newPort, mergedProps, this.getSocketFactoryClassName(), this.getProxy(), this.getSocketTimeout(), this.largeRowSizeThreshold.getValueAsInt());
        this.io.doHandshake(this.user, this.password, this.database);
    }

}

public class MysqlIO {
	// 链接就是socket
    protected Socket mysqlConnection = null;
    protected String host = null;
	protected int port = 3306;
	......

public MysqlIO(String host, int port, Properties props, String socketFactoryClassName, MySQLConnection conn, int socketTimeout, int useBufferRowSizeThreshold) throws IOException, SQLException {
        this.connection = conn;
        this.port = port;
        this.host = host;
        this.socketFactory = this.createSocketFactory();
		......
        try {
        // socket工厂创建socket,跟数据库建立链接
            this.mysqlConnection = this.socketFactory.connect(this.host, this.port, props);
		......
        } catch (IOException var10) {
            throw SQLError.createCommunicationsException(this.connection, 0L, 0L, var10, this.getExceptionInterceptor());
        }
    }
}

关系

Connection 封装了 socket
DataSource 封装了 Connection
TransactionManager 管理 Connection

声明式事务|Spring事务传播属性

propagation=“REQUIRED”
在这里插入图片描述

数据库事务隔离级别

isolation=“REPEATABLE_READ”
在这里插入图片描述

脏读、幻读、不可重复读

在这里插入图片描述

Spring事务隔离级别

isolation=“REPEATABLE_READ”
在这里插入图片描述

流程

判断是否是readonly,是:自动提交设置为true,不是:自动提交设置为false(才能回滚)
在这里插入图片描述

事务回滚机制

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值