python导入数据库报错:ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效---问题解决

本文介绍了解决Python脚本在操作Oracle数据库时遇到的ORA-00054错误的方法。该错误通常是因为未提交的事务导致表被锁定。通过提交未完成的事务,可以解除表锁定状态,从而使数据能够成功写入。

python导入数据库报错:ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效—问题解决

今天在对爬虫入库的脚本进行修改时,突然报错:ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效,想到之前测试脚本有无问题时在oracle中将数据插入目标表后没有提交,导致该表处于被锁状态,所以报错,点击如图所示的提交按钮后(也可以直接运行commit;命令),重新运行爬虫,数据成功插入!

在这里插入图片描述
oracle凡是涉及增删改一定要commit!切记!切记!

### 解决 MyBatis 中 ORA-00054 资源正忙 NOWAIT 错误 ORA-00054Oracle 数据库中常见的错误之一,表示尝试获取锁的资源当前正在被其他会话占用,并且由于指定了 `NOWAIT` 参数而无法等待资源解锁。此问题通常发生在并发事务较高的场景下。 #### 1. **分析问题** MyBatis 在操作数据库时可能触发该错误的原因主要包括以下几点: - 并发更新同一数据记录。 - 长时间运行的事务未提交或回滚,导致锁定资源未能及时释放。 - 存在死锁情况,某些会话处于挂起状态。 为了有效解决这一问题,可以从以下几个方面入手: --- #### 2. **通过 SQL 查询锁定资源的会话** 首先需要定位哪些会话占用了目标资源。可以使用如下查询语句找到相关会话的信息[^2]: ```sql SELECT s.sid, s.serial#, s.username, s.status, o.object_name FROM v$locked_object l JOIN dba_objects o ON l.object_id = o.object_id JOIN v$session s ON l.session_id = s.sid; ``` 上述查询返回的结果将显示锁定对象的相关信息以及对应的会话 ID 和序列号 (`SID`, `SERIAL#`)。 --- #### 3. **终止占用资源的会话** 一旦确认了具体的会话信息,可以通过以下命令杀死对应会话: ```sql ALTER SYSTEM KILL SESSION 'sid,serial#'; ``` 例如,假设查询到的 `SID=2170`,`SERIAL#=36796`,则执行以下语句: ```sql ALTER SYSTEM KILL SESSION '2170,36796'; ``` 需要注意的是,如果此时仍然收到 `ORA-00031: session marked for kill` 的提示,则说明会话已被标记为“已杀死”,但其持有的锁尚未完全释放。这可能是由于长时间运行的操作还未完成所致。 --- #### 4. **操作系统层面强制结束进程 (最后手段)** 当数据库级别的处理无效时,可以在操作系统层面上查找并终结相应的后台进程。具体步骤取决于所使用的操作系统环境。以下是 Linux 下的一个示例流程[^1]: 1. 查找与指定 SID 对应的 OS 进程编号: ```bash ps -ef | grep ora_ | grep <sid> ``` 2. 终止发现的进程: ```bash kill -9 <pid> ``` 注意:这种方法仅应在必要情况下采用,因为可能会引发一致性问题或其他副作用。 --- #### 5. **优化应用逻辑减少冲突可能性** 除了直接干预外,还可以从程序设计角度出发降低此类异常发生的概率: - **设置合理的超时参数** 如果允许等待一段时间后再决定是否放弃访问请求,可在 JDBC URL 或者 MyBatis 配置文件中调整连接属性,比如增加 `WAIT` 时间而非立即抛出异常。 - **批量操作拆分** 当涉及大量数据修改时考虑将其分割成更小批次逐步完成,从而缩短单次事务持续周期。 - **加锁策略改进** 利用乐观锁机制代替悲观锁能够显著缓解因频繁争抢相同行而导致的竞争状况。 --- ### 示例代码片段 下面给出一段简单的 Java + MyBatis 实现带重试功能的数据更新逻辑作为参考: ```java public void updateWithRetry(int retryCount) throws SQLException { int attempt = 0; boolean success = false; while (!success && attempt++ < retryCount) { try { sqlSession.update("yourMapperNamespace.yourUpdateStatement"); sqlSession.commit(); success = true; } catch (SQLException e) { if ("ORA-00054".equals(e.getErrorCode())) { System.out.println("Resource busy detected on attempt " + attempt); Thread.sleep(100); // Short delay before next trial. } else { throw e; // Re-throw unexpected exceptions immediately. } } } if (!success) { throw new RuntimeException("Failed after all retries."); } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值