SQLException:Object has closed

本文介绍了一个使用Java进行数据库操作的具体案例,包括记录的查询、价格更新等操作,并针对出现的Object has closed异常进行了初步分析。
 
  1. String insertRecordSql="select distinct depcity,arrcity,cabin,flightdate from TM_download where id>="+startId;  DBConnection  con=new DBConnection();  ResultSet record=con.executeQuery(insertRecordSql);  
  2. con=null;  
  3. con=new DBConnection();  
  4. String cabin;  
  5. String airline; 
  6. String update;//="update TM_download set price=";  
  7. try{  
  8.     while(record.next()){  
  9.          update="update TM_download set price=";  
  10.          cabin=record.getString("cabin");  
  11.          String depcity=record.getString("depcity");  
  12.          String arrcity=record.getString("arrcity");  
  13.          java.sql.Date flightdate=record.getDate("flightdate");  
  14.          airline=depcity+"-"+arrcity;  
  15.          Float cabinDisCoutF=(Float)cabinDiscount.get(cabin);  
  16.          Integer airlinePriceInt=(Integer)airlinePrice.get(airline);  
  17.          int cabinPrice=0;  
  18.          if(cabinDisCoutF!=null)  
  19.                         cabinPrice=getCommonPrice(airlinePriceInt.intValue(),cabinDisCoutF.floatValue());  
  20.          else  
  21.              cabinPrice=getSpecialcabinPrice(cabin,flightdate);  
  22.                     update=update+cabinPrice+" where cabin='"+cabin+"' and depcity='"+depcity+"' and arrcity='"+arrcity+"' and id>="+startId;     
  23.              con.executeUpdate(update);  
  24.              System.out.println("calculateCabinPrice sql:"+update);  
  25.       }  
  26. }catch(SQLException sqle){  
  27.      sqle.printStackTrace();  
  28. }finally{  
  29.      con.close();  

              程序缺少第3行时,整个while循环会执行一次,然后抛出Object  has closed 异常。具体原因还要进一步查证
package com.xzy.jxc.filter; import com.xzy.jxc.entity.TenantConfig; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import jakarta.annotation.PostConstruct; import org.apache.shardingsphere.broadcast.config.BroadcastRuleConfiguration; import org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory; import org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource; import org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration; import org.apache.shardingsphere.infra.config.rule.RuleConfiguration; import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration; import org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.SQLException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @Component public class DataSourceManager { private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>(); private ShardingSphereDataSource shardingDataSource; @Autowired private DataSourceProperties mainDataSourceProps; private DataSource mainDataSource; // 主库数据源单独管理 private Collection<RuleConfiguration> rules; // 保存规则配置 public synchronized DataSource getOrCreateDataSource(TenantConfig tenantConfig) { String dsKey = "tenant_ds:" + tenantConfig.getTenantId(); return dataSourceMap.computeIfAbsent(dsKey, key -> { HikariDataSource ds = createTenantDataSource(tenantConfig); refreshShardingDataSource(); // 动态刷新配置 return ds; }); } @PostConstruct public void initShardingDataSource() throws SQLException { // 1. 初始化主库(不放入 tenantDataSourceMap) mainDataSource = createHikariDataSource(mainDataSourceProps); // 2. 构建规则并创建 ShardingSphere 数据源 refreshShardingDataSource(); } /** * 动态刷新 ShardingSphere 数据源 */ private void refreshShardingDataSource() { try { // 合并主库和租户库数据源 Map<String, DataSource> allDataSources = new HashMap<>(); allDataSources.put("main_db", mainDataSource); // 主库固定名称 allDataSources.putAll(dataSourceMap); // 关闭旧的 ShardingSphere 数据源(不关闭底层连接池) if (shardingDataSource != null) { shardingDataSource.close(); } // 创建新数据源(复用现有连接池) Properties props = new Properties(); props.setProperty("sql-show", "true"); shardingDataSource = (ShardingSphereDataSource) ShardingSphereDataSourceFactory .createDataSource(allDataSources, buildAllRules(), props); } catch (SQLException e) { throw new RuntimeException("数据源刷新失败", e); } } /** * 构建所有规则配置(分片规则 + 广播规则) */ private Collection<RuleConfiguration> buildAllRules() { // 1. 分片规则 ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.getShardingAlgorithms().put( "tenant_algorithm", new AlgorithmConfiguration( "CLASS_BASED", new Properties() {{ setProperty("strategy", "STANDARD"); setProperty("algorithmClassName", "com.xzy.jxc.filter.TenantDatabaseShardingAlgorithm"); }} ) ); shardingRuleConfig.setDefaultDatabaseShardingStrategy( new StandardShardingStrategyConfiguration("tenant_id", "tenant_algorithm") ); // 2. 广播规则 BroadcastRuleConfiguration broadcastRule = new BroadcastRuleConfiguration( Collections.singletonList("tenant_config") ); // 3. 整合所有规则 return Arrays.asList(shardingRuleConfig, broadcastRule); } /** * 创建租户数据源 */ private HikariDataSource createTenantDataSource(TenantConfig config) { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setJdbcUrl(config.getJdbcUrl()); hikariConfig.setUsername(config.getUsername()); hikariConfig.setPassword(config.getPassword()); hikariConfig.setConnectionTimeout(30000); hikariConfig.setMaximumPoolSize(20); hikariConfig.setMinimumIdle(5); return new HikariDataSource(hikariConfig); } public DataSource getShardingDataSource() { return shardingDataSource; } /** * 创建主库数据源 */ private DataSource createHikariDataSource(DataSourceProperties props) { HikariConfig config = new HikariConfig(); config.setJdbcUrl(props.getUrl()); config.setUsername(props.getUsername()); config.setPassword(props.getPassword()); config.setMaximumPoolSize(10); config.setIdleTimeout(600000); config.addDataSourceProperty("connectionTestQuery", "SELECT 1"); config.setConnectionTimeout(30000); config.setDriverClassName("com.mysql.cj.jdbc.Driver"); config.addDataSourceProperty("cachePrepStmts", "true"); return new HikariDataSource(config); } public Map<String, DataSource> getDataSourceMap() { Map<String, DataSource> allDataSources = new HashMap<>(); allDataSources.put("main_db", mainDataSource); allDataSources.putAll(dataSourceMap); return Collections.unmodifiableMap(allDataSources); } } 系统异常org.apache.shardingsphere.infra.exception.core.external.sql.type.wrapper.SQLWrapperException: More details: java.sql.SQLException: HikariDataSource HikariDataSource (HikariPool-1) has been closed.
05-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值