Waiting for table metadata lock引发java.sql.SQLException: No operations allowed after statement closed

项目场景:

应用报错java.sql.SQLException: No operations allowed after statement closed


问题描述

接口报错后,show processlist 检查数据库,发现等待锁释放 Waiting for table metadata lock
在这里插入图片描述


原因分析:

mysql中如果一个表产生了Waiting for table metadata lock,针对表的任何操作都会被锁住,包括select,可以通过配置参数lock_wait_timeout减少等待时长。No operations allowed after statement closed原因是存在未提交事物,阻塞DDL,继而阻塞所有同表的后续操作

问题复现:

未提交事务:

begin;
select * from resource_yarn_queue_metadata limit 1;

DDL操作(表是一个分区表,通过自动化脚本定时新增分区)

ALTER TABLE resource_yarn_queue_metadata ADD PARTITION (
    PARTITION p20240610 VALUES LESS THAN (739413)
);

解决方案:

查找未提交事务id,kill

select t.PROCESSLIST_ID,
       t.PROCESSLIST_USER,
			 t.PROCESSLIST_HOST,
			 t.PROCESSLIST_DB,
			 t.PROCESSLIST_STATE,
			 t.PROCESSLIST_COMMAND,
			 t.PROCESSLIST_TIME,
			 t.PROCESSLIST_INFO,
			 e.CURRENT_SCHEMA,
			 GROUP_CONCAT(e.SQL_TEXT SEPARATOR ' ') as sqL_text
from performance_schema.threads t,
		 information_schema.INNODB_TRX trx,
		 performance_schema.events_statements_history e
where t.THREAD_ID = e.THREAD_ID
      and t.PROCESSLIST_ID = trx.trx_mysql_thread_id
group by t.THREAD_ID DESC;
kill 1125440;
`java.sql.SQLException: Column Index out of range, 5 > 4` 是一个常见的 SQL 异常,表示在尝试访问结果集中的某一列时,指定的列索引超出了实际存在的列数范围。 具体来说,这个错误信息告诉我们: - 你试图访问第 5 列(索引从 1 开始计数),但结果集中只有 4 列。 导致这个错误的常见原因包括: 1. **查询语句返回的列数少于预期**:检查你的 SQL 查询语句,确保它返回了足够的列。 2. **代码中硬编码的列索引不正确**:如果你在代码中硬编码了列索引,请确保这些索引在当前结果集的范围内。 3. **数据库表结构变化**:如果数据库表的结构发生了变化,而你的代码没有同步更新,也可能导致这个问题。 ### 示例 假设你有一个 SQL 查询如下: ```sql SELECT id, name, age, address FROM users; ``` 这个查询返回 4 列。如果你在代码中尝试访问第 5 列,就会抛出 `SQLException`。 ### 解决方法 1. **检查 SQL 查询**:确保你的查询返回了足够的列。 ```sql SELECT id, name, age, address, email FROM users; ``` 2. **验证列索引**:在代码中,确保你访问的列索引在有效范围内。例如: ```java ResultSet rs = statement.executeQuery("SELECT id, name, age, address FROM users"); while (rs.next()) { int id = rs.getInt(1); // 正确 String name = rs.getString(2); // 正确 int age = rs.getInt(3); // 正确 String address = rs.getString(4); // 正确 // String email = rs.getString(5); // 错误,超出范围 } ``` 3. **动态获取列数**:如果你不确定结果集有多少列,可以使用 `ResultSetMetaData` 来动态获取列数。 ```java ResultSet rs = statement.executeQuery("SELECT id, name, age, address FROM users"); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); System.out.println("Number of columns: " + columnCount); ``` 通过以上方法,你可以有效地避免和解决 `Column Index out of range` 的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

但行益事莫问前程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值