摘自http://blog.itpub.net/12932950/viewspace-607691/

这两天一直在因为系统初期设计原因导致的一个触发器问题。
问题如下:
有表T,有客户编号、账户编号及地址三个字段(为方便起见以最少字段描述)。
一个客户编号下可能存在多个账户编号(3个或4个)。
假设客户编号C0下有A1、A2、A3三个账户编号。
        现在对账户编号A1的地址字段进行了更新,要求通过触发器同时更新客户编号C0下的另外两个账户A2和A3的地址字段。

通过实际的触发,发现存在着一个非常致命的问题:
       由于指定的是自治事务触发器(即指定了pragma autonomous_transaction),假设为T1。每次更新表时触发都是独立的。因此就产生了死循环和死锁的问题。
因为更新了A1,则T1触发。T1内去找到同个客户编号下的A2和A3。然后先更新A2,此时便又触发了T1。然后又找到同个客户编号下的A1和A3。然后先更新A1,而由于先前第一次更新已经锁住了A1,再次更新就会导致死锁。因为先前的A1更新需要现在的A1先完成。而现在的A1更新却被先前的A1更新阻塞了。
        从上面可以看出,如果可以找到这样一个办法,将锁住的行找出来,然后在每次更新之前都判断一下该行是否被锁住。如果锁住则跳到下一条记录进行处理。没锁住则继续更新。
       实际上这只是理想的情况,的确可以通过查询v$lock v$session v$locked_object查到被锁住的行:
select ta.account_no, o.object_name, ta.rowid
 from v$session s, ttest ta, user_objects o, v$locked_object lo
where lo.SESSION_ID = s.SID
  and lo.OBJECT_ID = o.object_id
  and dbms_rowid.rowid_object(ta.rowid) = o.data_object_id
  and o.object_id = s.ROW_WAIT_OBJ#
  and dbms_rowid.rowid_relative_fno(ta.rowid) =  s.ROW_WAIT_FILE#
  and dbms_rowid.rowid_block_number(ta.rowid) = s.ROW_WAIT_BLOCK#
  and dbms_rowid.rowid_row_number(ta.rowid) = s.ROW_WAIT_ROW#
但是通过实际调试发现。这个记录的并不是当时被锁住的所有记录。而是最后一次被锁住的一条记录。什么意思呢?也就是说当时可能有几条记录被锁住。但是这个SQL所查出来的是执行所有锁行操作的语句后,最后一次被锁住的行。也就是失去了即时判断的可能性。
       想通过另外的方法去找到这个被锁住的行我网上也搜索过无数遍了。都没有实际解决方案。可能这么做的人很少吧。
       最后想到了一个办法,就是通过临时表的方法去记录被更新的行。一旦触发T1,就往临时表记录这一行的rowid和对应的锁定标识。然后在更新的时候判断
是否已经存在于该表中。如果有则不更新,没有则往下更新。更新并提交后该行
锁标识清零。进入下一次循环。
       这个临时表是会话级的。因此在触发器循环触发过程中都是处于同一个数据环境下。方便了对指定行的加锁与解锁(其实是设定行锁定状态)。
下一篇准备讲述此次解决死锁问题而学习到的关于Oracle锁的一些方面的知识。
(备注:如果不指定自治事务触发器,则无法修改触发器触发所在的表)

[转][工地][存]Oracle触发器死锁问题解决的更多相关文章

  1. ORACLE中死锁的知识点总结

      死锁的概念 什么是死锁呢? 其实我们生活中也有很多类似死锁的例子. 我先举一个生活中的例子:过年回家,父亲买了一把水弹枪,儿子和侄子争抢着要先玩,谁也不让谁,拆开包装后,一个抢了枪, 一个逮住了子 ...

  2. ORACLE中死锁

    ORACLE中死锁的知识点总结   死锁的概念 什么是死锁呢? 其实我们生活中也有很多类似死锁的例子. 我先举一个生活中的例子:过年回家,父亲买了一把水弹枪,儿子和侄子争抢着要先玩,谁也不让谁,拆开包 ...

  3. 2014/11/06 Oracle触发器初步 2014-11-06 09:03 49人阅读 评论(0) 收藏

    触发器我就不多解释了,保证数据的完整性的神器,嗯..也是减少程序员工作托管给数据库操作的好帮手.就不讲一些大道理了.通俗点,我们对数据库的操作,无非就是增 删 改 查. 触发器就是在删,改,增的时候( ...

  4. 【原创】ORACLE常见使用问题解决

    ORACLE常见使用问题解决 一.安装了oracle客户端后,发现plsql客户端找不到之前已经配置过的TNS连接信息 或许大家再使用ORACLE软件的过程中,经常会遇到这样的问题: 问题现象描述: ...

  5. oracle触发器加条件判断

    oracle触发器加条件判断,如果某个字段,isnode=0,那么不执行下面的方法,数据如下: create or replace trigger tr_basestation_insert_emp ...

  6. Oracle 表死锁 解决

    问题:更新的Update语句一直在更新 卡在执行update语句的地方. 清除的方法: Oracle表死锁解除   我是在plsql中处理  1.先查询  select * from v$locked ...

  7. [转]连续创建多个Oracle触发器失败,单个创建才成功的解决方法

    连续创建多个Oracle触发器失败,单个创建才成功的解决方法   1.当我连续执行创建多个触发器时,总是报编译通过,但存在警告或错误.如下:   create or replace trigger t ...

  8. Oracle 触发器在日志管理开发中的应用

    摘要: 本文讨论了利用数据库中的触发器对日志管理进行设计与实现的方法, 是对原来在客户端软件中编写日志管理方法的一种改进, 并给出了 Oracle9i 中的实例演示.关键词: Oracle; 触发器; ...

  9. oracle触发器应用

    首先给大家推荐两篇我看后的博文,我已经内容转载过来: 1.对触发器的讲解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建 ...

随机推荐

  1. 301、404、200、304、500等HTTP状态,代表什么意思?

    一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务器超时 下面提供 HTTP 状态码的完整列表.点击链接可了解详情.您也可以访问 HTTP 状态码上的 ...

  2. 【函数】oracle translate() 详解+实例

      一.语法: TRANSLATE(string,from_str,to_str) 二.目的 返回将(所有出现的)from_str中的每个字符替换为to_str中的相应字符以后的string.TRAN ...

  3. 关于IE6浮动问题!

    以下内容均为个人笔记:望批评指教! IE6下应尽量少使用float 而是  换用display:inline  父层使用text-align:text:效果会好些: 如果一组浮动元素 产生了浮动 最好 ...

  4. PAT (Basic Level) Practise:1029. 旧键盘

    [题目链接] 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在2行中分别给出应该输入的 ...

  5. js foreach比for多出两个undefined

    项目中发现,javascript 用foreach会比for多出两个undefined, //会多两个undefined for (var i in _SysFunctions_S) {} //正常 ...

  6. 菜鳥日記:為 Github 添加 ssh

    這只是一篇求真務實言簡意賅的菜鳥日記 記錄了碼盲在OSX 中為Github添加 ssh 的過程 要從 Github 上克隆個源碼到本地,發現無 ssh 密鈅 於是開到官網幫助照貓畫虎如下: 1.打開 ...

  7. 数据处理项目Beta阶段软件架构建议

    class:Dataserver string serverIP string serverPassword string sqlAccount string sqlPassword bool Dat ...

  8. JavaWeb学习记录总结(二十九)--Servlet\Session\Cookie\Filter实现自动登录和记住密码

    一.Servlet package autologin.servlet.login; import java.io.IOException;import java.security.MessageDi ...

  9. FreeSWITCH安装报错“You must install libyuv-dev to build mod_fsv”的解决方案

    昨天下午安装FreeSWITCH时遇到该问题时,整了一个下午都没解决,也走了许多弯路.如果直接通过yum安装libyuv-devel时,会报错说找不到该安装包.后来又通过FreeSWITCH官网的网上 ...

  10. c程序代码优化的一些方法

    我认为一个好的用于科学计算的程序代码应该:算法漂亮精妙,程序简洁易懂,运算快速,节省内存.这里有的地方是矛盾的,比如简洁vs易懂,时间vs空间,找个平衡吧.目前来看时间要比空间宝贵一些.写程序分几步: ...