`

oracle锁bug

阅读更多
一、问题描述
两任务并发访问同一数据库表中的记录,出现死锁,如下是其中一个任务的代码:
  1. Connection dbConn = DAMContext.getConnection();  
  2. String userAccountSql = createAccountSql(exportDate);  
  3. List accountList = new ArrayList();  
  4. try {  
  5.     PreparedStatement pstm = dbConn.prepareStatement(userAccountSql,  
  6.         ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);  
  7.     ResultSet result = pstm.executeQuery();  
  8.     while (result.next()) {  
  9.         UserAccount account = new UserAccount();  
  10.         //omited  
  11.         accountList.add(account);  
  12.     }  
  13.   
  14.     String updateSql = createExpireSql(exportDate);  
  15.     PreparedStatement updatePs = dbConn.prepareStatement(updateSql,  
  16.            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); 
  17.     //ResultSet.CONCUR_READ_ONLY 表示sql语句不会做更新处理,  
  18.     //这就意味者在操作这批记录时,不会首先获取这批记录的"页锁",别人仍旧可以同时对这批数据进行并发的update操作。  
  19.   
  20.     ResultSet updateResult = updatePs.executeQuery();  
  21.     //执行update操作  
  22.     //在dbConn.prepareStatement()中指定的是不做update处理,而实际上却执行了update操作  
  23.     //导致更新这批记录时:更新到某条记录时,才获取这条记录的"独占行锁"。  
  24.     //这就留下了发生死锁的隐患:在执行过程中,一部分已更新的记录集(A)获取了锁;另一部分还没有更新的记录集(B)没有获取锁  
  25.     //如果此时,有另一线程已经update了记录集(B)中的记录,并且未释放锁;同时又等待记录集(A)中记录的锁来进行update操作,这样死锁就发生了。  
  26. }  
  27. catch (Exception e) {  
  28.     e.printStackTrace();  
  29.     try {  
  30.         dbConn.rollback();  
  31.     }  
  32.     catch (SQLException _ex) {  
  33.         _ex.printStackTrace();  
  34.     }  
  35. }  
  36. finally {  
  37.     try {  
  38.         dbConn.setAutoCommit(true);  
  39.     }  
  40.     catch (SQLException _ex) {  
  41.         _ex.printStackTrace();  
  42.     }  
  43.     finally {  
  44.         DAMContext.freeConnection(dbConn);  
  45.     }  
  46. }  

二、解决方案一
确保两个线程访问同一个数据库表的记录的顺序都是一致的。
因为:假设线程(一)目前处理的状况是已更新的为数据集A,剩下未更新的为数据集B;由于两线程访问数据库表的顺序是一致的,故必须是先访问数据集A中的记录,然后再访问数据集B中的记录,因此线程(二)肯定是先访问数据集A中的记录,而此时必须等待,直至线程(一)commit或rollback释放全部的“行锁”。

三、解决方案二
  1. PreparedStatement updatePs = dbConn.prepareStatement(updateSql,  
  2.        ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);  
修改为:
  1. PreparedStatement updatePs = dbConn.prepareStatement(updateSql,  
  2.        ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);  

ResultSet.CONCUR_UPDATABLE 表示sql语句是要做更新操作,那么在更新这批记录集前,就会先拿到"页锁";如果这批记录集的部分记录的“行锁”未释放,则等待这批记录的“行锁”全部释放,获取“页锁”。在“页锁”释放掉之前,别人不可能拿到这批记录集中的任何一条记录的“行锁”,也就不可能发生死锁。


分享到:
评论

相关推荐

    ORACLE Bug 17588480

    标题:“ORACLE Bug ***”描述了Oracle数据库中的一个特定错误,该错误与库缓存互斥锁/共享池锁死锁问题有关。官方说明文档提供了关于该Bug的概述、影响的产品版本、固定该问题的补丁信息以及一些解决问题的建议。 ...

    怎样快速查出Oracle 数据库中的锁等待

    Oracle 数据库锁等待问题解决方案 Oracle 数据库系统中,为了保证数据的一致性,在对数据库中的数据进行操作时,系统会进行对数据相应的锁定。这些锁定中有"只读锁"、"排它锁"、"共享排它锁"等多种类型,每种类型...

    如何解决Oracle杀死死锁进程

    * 死锁问题可能是由于数据库设计的缺陷或应用程序的 Bug 导致的,需要对数据库和应用程序进行优化和改进。 解决 Oracle 杀死死锁进程需要具备扎实的 Oracle 基础知识和解决问题的经验。通过学习和实践,可以更好地...

    Oracle数据库性能优化实务_闩锁及闩锁优化.pptx

    Oracle数据库性能优化实务主要关注的是闩锁(LATCH)及其优化,这关乎数据库系统的稳定性和效率。闩锁是Oracle数据库内部用于控制并发访问共享内存结构的一种机制,它们确保了核心内存访问的一致性和高效性。 ...

    小机上运行ORACLE需要注意的进程调度BUG

    ### 小机上运行Oracle需要注意的进程调度Bug详解 #### 一、问题背景与描述 在小机上运行Oracle数据库时,可能会遇到一种特殊的Bug,表现为应用间歇性局部挂起的问题。根据客户的反馈,这类问题的具体表现是:在...

    oracle性能优化

    5. 应用补丁和升级:在某些情况下,性能问题可能是由于Oracle软件中的bug导致,这时候应用最新的补丁或升级到最新版本可以解决性能问题。 6. 分布式处理和硬件升级:如果问题是由系统硬件资源不足导致的,那么可能...

    Oracle命令行运维工具oclient

    同时修增加异常锁,大事务,会话详情等实用功能,方便运维人员定位问题。常用功能输入错误时增加了友好提示。最后修改了许多BUG更进一步增强了Oclient工具的可用性和健壮性。 Oclient V3.0在Oclient V2.0基础上增加...

    spotlight_for_oracle_rac.5.0.1.1022.zip

    5. 故障诊断:通过分析会话、锁、等待事件等,Spotlight能帮助DBA快速诊断并解决问题。 6. 容量规划:根据历史数据预测未来资源需求,辅助进行容量规划。 7. 整合报告:自定义报告功能,让DBA可以定期获取系统状态...

    CSDN Oracle 版精华帖荟萃

    另外,关于证明两段锁协议的事务调度处理结果可串行化的讨论,这对于数据库事务的并发控制理论具有重要意义,关系到数据库在多用户环境下数据一致性问题的处理。 对于没有备份控制文件误删除的情况,如何进行恢复是...

    Oracle数据库运维案例介绍.pptx

    4. 检查Oracle版本和补丁:确保已安装最新的补丁,防止因已知BUG导致的问题。 5. 使用排除法:逐一排查可能的因素,例如网络、硬件、操作系统设置等,直到找到问题根源。 最后,根据故障的严重程度和持续时间,可能...

    修改oracle密码有效期限制的两种思路详解

    由于项目的一个bug,导致好几个现网项目都出现了异常。 bug说明: oracle11g,静默安装后用户的密码有效期默认设置为180天,180天后密码将失效,oracle会提示要修改密码。 我们项目用的是jdbc连接oracle数据库,没法...

    航空售票系统修改Bug

    修复Bug可能需要调整预订逻辑,如增加锁机制,或者优化并发控制策略。 最后,压缩包中的“解释”文件很可能是开发者对于修改的详细说明,包括Bug的产生原因、修复过程和测试结果。这部分内容对于其他开发者来说是...

    基于java的Oracle数据库工具 WARTS.zip

    - 作为一款全面的数据库工具,WARTS可能提供数据库性能监控功能,如查看SQL执行计划、分析慢查询、监控数据库锁等,帮助DBA优化数据库性能。 7. **安全性与权限控制** - WARTS会根据用户角色和权限设定,限制不同...

    ORACLE数据库应用开发常见问题及排除

    在多用户环境中,理解并有效利用ORACLE的锁机制,如行级锁和表级锁,是确保并发性能的关键。 总之,ORACLE数据库应用开发涉及的问题多样且复杂,需要开发者具备扎实的数据库理论知识、良好的编程习惯以及对ORACLE...

    泛微OA数据库相关问题处理

    在ORACLE数据库中,SQL子查询带有ROWNUM时可能会触发ORACLE BUG,导致语句报错。解决这个问题可以使用ROWNUM的别名,例如: ```sql SELECT * FROM ( SELECT *, ROWNUM r FROM ( SELECT * FROM table_name ) ) ...

    slot_map.rar_V2

    ocfs2(Oracle Cluster File System version 2)是一种集群文件系统,设计用于多节点环境,它允许多台服务器共享同一文件系统,提供高可用性和数据一致性。在ocfs2中,slot映射是其分布式锁管理器(DLM)的关键组件...

    PLSQL Developer 12 (32 位).rar

    5. **联网升级**:PLSQL Developer允许用户通过网络更新到最新版本,以获取最新的功能和修复的bug。这保证了用户始终可以使用到功能最全面、最安全的软件版本。 6. **注册码**:软件通常需要激活才能正常使用,注册...

    DBATools For PL/SQL Developer

    3.* 修正了V1.0.0正式版中列表中数字列按字符排序的BUG --------------------------------------------------------------- [2009-01-22]发布 DBATools For PL/SQL Developer 1.0.0 正式版本更新说明 --------------...

Global site tag (gtag.js) - Google Analytics