MyDynamicRoutingDataSource.java 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package jnpf.database.plugins;
  2. import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
  3. import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
  4. import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
  5. import com.baomidou.dynamic.datasource.tx.ConnectionFactory;
  6. import com.baomidou.dynamic.datasource.tx.ConnectionProxy;
  7. import com.baomidou.dynamic.datasource.tx.TransactionContext;
  8. import jnpf.constant.MsgCode;
  9. import jnpf.database.util.ConnUtil;
  10. import jnpf.database.util.DynamicDataSourceUtil;
  11. import jnpf.database.util.TenantDataSourceUtil;
  12. import jnpf.exception.ConnectDatabaseException;
  13. import jnpf.util.TenantHolder;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.springframework.util.StringUtils;
  16. import javax.sql.DataSource;
  17. import java.sql.Connection;
  18. import java.sql.SQLException;
  19. import java.util.List;
  20. /**
  21. * 自定义动态数据源类
  22. * @author JNPF开发平台组
  23. * @user N
  24. * @copyright 引迈信息技术有限公司
  25. * @date 2022/10/8 16:06
  26. */
  27. @Slf4j
  28. public class MyDynamicRoutingDataSource extends DynamicRoutingDataSource {
  29. public MyDynamicRoutingDataSource(List<DynamicDataSourceProvider> providers) {
  30. super(providers);
  31. }
  32. @Override
  33. public Connection getConnection() throws SQLException {
  34. String xid = TransactionContext.getXID();
  35. String ds = DynamicDataSourceContextHolder.peek();
  36. if(DynamicDataSourceUtil.isPrimaryDataSoure() && TenantHolder.isRemote()){
  37. //租户系统指定数据源, 如果当前源为主库 直接切换至指定源, 处理事务开启时Spring先行获取连接未切库问题
  38. ds = TenantDataSourceUtil.getTenantAssignDataSourceMasterKeyName();
  39. }
  40. if (!StringUtils.hasText(xid)) {
  41. return getMyDataSource(ds);
  42. } else {
  43. String tKey = !StringUtils.hasText(ds) ? "default" : ds;
  44. ConnectionProxy connection = ConnectionFactory.getConnection(xid, tKey);
  45. return connection == null ? getConnectionProxy(xid, tKey, getMyDataSource(ds)) : connection;
  46. }
  47. }
  48. private Connection getMyDataSource(String dsKey) throws SQLException {
  49. try{
  50. DataSource dataSource = getDataSource(dsKey);
  51. Connection connection = dataSource.getConnection();
  52. ConnUtil.switchConnectionSchema(connection);
  53. return connection;
  54. }catch (SQLException e){
  55. //移除运行中动态创建的数据源
  56. //避免第三方数据库关闭后一直尝试重新创建连接
  57. if (DynamicDataSourceUtil.containsLink(dsKey)) {
  58. try {
  59. //Druid数据源如果正在获取数据源 有概率连接创建线程无法停止
  60. //if(((ItemDataSource) dataSource).getRealDataSource() instanceof DruidDataSource){
  61. // ((DruidDataSource) ((ItemDataSource) dataSource).getRealDataSource()).setBreakAfterAcquireFailure(true);
  62. //}
  63. removeDataSource(dsKey);
  64. } catch (Exception ee) {
  65. log.error("关闭动态数据源【" + dsKey + "】失败", ee);
  66. }
  67. }else if(TenantHolder.isRemote()){
  68. //租户指定数据源 连接失败全部移除
  69. TenantDataSourceUtil.removeAllAssignDataSource();
  70. }
  71. throw new ConnectDatabaseException(MsgCode.DB302.get(), e);
  72. }
  73. }
  74. private Connection getConnectionProxy(String xid, String ds, Connection connection) {
  75. ConnectionProxy connectionProxy = new ConnectionProxy(connection, ds);
  76. ConnectionFactory.putConnection(xid, ds, connectionProxy);
  77. return connectionProxy;
  78. }
  79. }