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 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; } }