zhubaomin
2025-04-11 d1e380d5bc8d6cda7dc26778dd638b3367483ae7
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/multiDataSource/MultiDataSourceTransaction.java
New file
@@ -0,0 +1,86 @@
package com.dy.common.multiDataSource;
import org.apache.ibatis.transaction.Transaction;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
 * 多数据源的事务类,事务对象由事务工厂创建,完成数据库事务操作。
 * 事务对象包裹着:
 *   数据库连接、事务提交、事务回滚等对象及操作
 * 在事务对象中具体决定采用的具体数据源
 */
public class MultiDataSourceTransaction implements Transaction {
    private final DataSource multidataSource;
    private final ConcurrentMap<String, Connection> curConMap;
    private boolean autoCommit;
    public MultiDataSourceTransaction(DataSource dataSource, boolean autoCommit) {
        //dataSource是DynamicDataSource类的实例
        this.multidataSource = dataSource;
        this.autoCommit = autoCommit;
        curConMap = new ConcurrentHashMap<>();
    }
    @Override
    public Connection getConnection() throws SQLException {
        String nowDsName = DataSourceContext.get();
        if (nowDsName == null || "".equals(nowDsName)) {//StringUtils.isEmpty(databaseIdentification)
            //databaseIdentification = DataSourceName.USERDATASOURCE.getName();
            throw new CannotGetJdbcConnectionException("未得到数据源名称");
            //nowDsName = "ym" ;
        }
        //获取数据源连接
        if (!this.curConMap.containsKey(nowDsName)) {
            try {
                Connection conn = this.multidataSource.getConnection();
                this.autoCommit = false;
                conn.setAutoCommit(false);
                this.curConMap.put(nowDsName, conn);
            } catch (SQLException ex) {
                throw new CannotGetJdbcConnectionException("未得到数据源JDBC连接", ex);
            }
        }
        return this.curConMap.get(nowDsName);
    }
    @Override
    public void commit() throws SQLException {
        for (Connection connection : curConMap.values()) {
            if (!autoCommit) {
                connection.commit();
            }
        }
    }
    @Override
    public void rollback() throws SQLException {
        for (Connection connection : curConMap.values()) {
            connection.rollback();
        }
    }
    @Override
    public void close() throws SQLException {
        for (Connection connection : curConMap.values()) {
            DataSourceUtils.releaseConnection(connection, this.multidataSource);
        }
    }
    @Override
    public Integer getTimeout() throws SQLException {
        return null;
    }
}