EBS_FORM_开发:关于LOCK-ON

假死锁问题:

留着解决以后分享问题的解决思路.

转:http://tech.it168.com/a2009/0428/274/000000274236_4.shtml

1、错误提示:

  

  2、原理知识:

  2.1当我们在Forms中,试图更改block中数据的时候,Forms先发出一个对该行数据的select ... for update nowait查询,希望锁定该行(该锁是ORACLE行级X锁)。如果不能锁定,Forms提示Could not reserve records (2 trys). Keep trying?。如果用户选择No,Forms报告FRM-40510错误:ORACLE error: unable to reserve record for update or delete。

  2.2 block加锁的模式。

  

  block的锁定模式如果为automatic或immediate,会在修改记录时Forms会立即锁定数据库记录;如果设为delayed,在保存时Forms才尝试锁定记录。也就是说这个属性不管如何设置,都不会影响锁的模式,有影响的只是什么时候加锁而已。

  2.4上面已经说过了,Forms在更数据行时,会先对该数据行加行级X锁。这个是Oracle写死在Forms中的,我们无法手工修改。你想不加锁也不行!Oracle够野蛮吧!^_^。不要拿Oracle推荐的transaction来压我,要明白这个世界上,不是全部的业务应用都需要严格的transaction。

  2.5即使前面的查询锁定步骤成功,Forms还要比较查询结果和当前行的值是否一致。如果两者不完全相同,Forms抛出FRM-40654(记录已经被另一个用户更新,重新查询以查看修改)错误。这么做主要是为了防止lost update的情形,不让用户根据过时的数据来做出修改。这一点请认真理解哦?

  3、解决方法:

  3.1避免在TRIGGER中直接使用UPDATE语句,这样会造成Forms上的数据与Oracle数据库的数据不一致,从而造成FRM-40654的错误。

  3.2要是问题都是由方法3.1造成的,那么它就不是问题了。

  3.2.1下面细讲造成这次造成Form假死锁的根本原因。被锁的记录-订单编号为2000000747:

  

  3.2.2注意认真查看这条记录,我们注意到3967.8这个字段。^_^,至于为什么会注意到这个字段。我折腾了一周多,并且在ITPUB上反复认真学习FORM底层数据操作的原理,再加N*N次方TEST,最后才锁定这个字段。3967.8是“供方承担”的金额字段。经查数据字典又得知数据库字段名为“supply_pay”

  3.2.3我们直接从数据库SELECT这个记录出来看看。

  select hm.oe_head_number,hm.supply_pay from hek_ods_th_fee_m hm where hm.oe_head_number=‘2000000747‘

  

  看清楚了吗?supply_pay数据库的值为3967.799796,而FORM界面上的值却为3967.8。也就是说FORM自动帮我们四舍五入了。这样我们在FORMS上MODIFY这条记录时,FORM就会判断3967.8<>3967.799796,从而报FRM-40654的错误。而我们呢?却被误导一直在数据库锁方面找问题。

  

  于是,我们总结出,可恶的ORACLE自作聪明,帮我们四舍五入了。可是我们真需要四舍五入吗?就算是要,自已加个ROUND不就得了吗?这不能不说是FORMS一个BUG!这也再次提醒我们不能对ORACLE太崇拜了哦?

时间: 2024-10-19 10:54:09

EBS_FORM_开发:关于LOCK-ON的相关文章

EBS_FORM_开发:关于WHEN-VALIDATE-ITEM上面commit

在这里form builder不允许commit_form 于是想着用  forms_ddl('COMMIT');  一实验果然可以实现: --mend行 sum分拷贝到mid行 copy(name_in('mend.SUM_SCORE'),'mid.SUM_SCORE_M'); --copy(name_in('mid.STD_SCORE'),'mid.SUM_SCORE_M'); --fnd_message.debug(:mend.SUM_SCORE); --fnd_message.debug

EBS_FORM_开发:关于离开record验证

--WHEN-VALIDATE-RECORD IF :mend.MEND_CAUSE is  null THEN         FND_MESSAGE.SET_STRING('请输入评价原因!!');          FND_MESSAGE.SHOW; RAISE form_trigger_failure;END IF; 错误的原因: IF :mend.MEND_CAUSE is not null then          null;ELSIF :mend.MEND_CAUSE is  n

EBS_FORM_开发:实现form record ctrl+F6复制

1.先写 /*===================================== ** PROCEDURE: DEFAULT_ROW() **=====================================*/ PROCEDURE DEFAULT_ROW IS BEGIN :LINES.HEADER_ID := :HEADERS.HEADER_ID; IF :LINES.LINE_ID IS NULL THEN SELECT CUX_HRSC_LINES_S.NEXTVAL I

Java并发编程之---Lock框架详解

Java 并发开发:Lock 框架详解 摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等.Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题.本文以synchronized与Lock的对比为切入点,对Java中的Lock框架的枝干部分进行了详细介绍,最后给出了锁的一些相关概念. 一

.net 开发人员的瓶颈和职业发展

From:http://www.cnblogs.com/PurpleTide/archive/2012/05/16/2502547.html 现在社会比前几年浮躁了,越来越多的人抱怨薪水低,高薪工作不好找; 诚然这有CPI的压力,可是也有很多人没有认清自己的职业发展. 很多.net程序员个各种纠结,想拿高薪又拿不到,想提高又不知道怎么能提高. 我也经历过这样的阶段.......各种纠结和迷茫,各种悲剧......不知道路在何方,在此我把我的经验和看法分享给大家,希望能给大家一点帮助. (本文只代

.NET开发人员的瓶颈和职业发展

现在社会比前几年浮躁了,越来越多的人抱怨薪水低,高薪工作不好找; 诚然这有CPI的压力,可是也有很多人没有认清自己的职业发展. 很多.net程序员个各种纠结,想拿高薪又拿不到,想提高又不知道怎么能提高. 我也经历过这样的阶段.......各种纠结和迷茫,各种悲剧......不知道路在何方,在此我把我的经验和看法分享给大家,希望能给大家一点帮助. (本文只代表我的个人观点) 关于职业/薪水瓶颈的问题: (在本文中,我们假设薪水就是能力的真实体现,不考虑运气等因素,并且薪水以上海为标准,其他城市乘以

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

python全栈开发基础【第二十四篇】(利用threading模块开线程、join与守护线程、GIL与Lock)

一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 创建线程的开销比创建进程的开销小,因而创建线程的速度快. #开启进程的第一种方式 from multiprocessing import Process from threading import Thread import os import time def work(): print('<%s> is running'%os.g

C#多线程开发6:使用lock语句同步多个线程

在多个线程之间共享数据时,需要考虑线程同步问题,必须确保每次只有一个线程访问和改变共享数据. C#中使用lock语句可以轻松地设置和解除锁定以期达到每次只有一个线程访问和改变共享数据的目的. 下面是一个多线程访问共享数据的实例,看看在没有进行同步操作的情况下会出现什么样的问题? using System; using System.Threading; namespace LockExamples { class Program { static int account = 1000;//账户