原文地址:http://radio-weblogs.com/0118231/stories/2004/03/24/whyDoIGetOraclejborowinconsistentexception.html
翻译了 前面一个英文的文章,关于处理 Another user has changed the row with primary key oracle.jbo.Key 的方法
oracle.jbo.RowInconsistentException 是BC4J框架告诉用户与用户最初查询
该VO相比,另一些用户改变了其VO中ROW的信息.这就是所谓的"丢失更新问题".在
一个序列中
如果两个用户试图修改同一行数据,是取决于用户使用的是pessimistic locking
还是optimistic locking.当用户使用pessimistic locking时,在更新EO字段时,
用户可以查看下报出的错误.或者在使用optimistic locking处理 post/commit
时查看显示的信息.我们的锁机制模式默认使用的是pessimistic locking,并且
通过设定一个像optimistic 的属性(jbo.locking.mode配置属性,你作让其为根
am为您的应用程序使用的am的配置)可以设置成全局性的。
用户可以使用BC4J tester(通过在您的AM中右键选择test)来模拟发生
此类错误的现象.通过test AM两次则两个AM Tester实例就运行起来了,两实例都
进行查询同一行,之后在一个tester windows中对该行做某个字段的值改变,提交
后当用户尝试在2nd窗口在该行进行改变一个字段时,用户则会导致
oracle.jbo.RowInconsistentException.如果用户取消默认的pessimistic
locking 模式,或者在提交时在配置中改为 jbo.locking.mode=optimistic.
如果用户的BC4J/ADF 程序报此异常,那么下面二者其一会发生:
在你检索此行时,真的会有其他用户更新此行数据
用户的程序 可能存在问题,会导致BC4J认为 该行被改变了,实际上并没有其他用
户真的改变其值.
当我们锁住一行进行更新时,我们对Oracle发出这样哪个
SELECT <list of all columns to which your entity object's persistent
attributes are mapped>
FROM <table name that your entity object is mapped to>
WHERE <primary key columns = current values of corresponding PK
attributes of entity>
FOR UPDATE NOWAIT
如果我们成功的锁住该行,那么我们就会独自拥有该行,并且在锁期间,我们可以
持久化EO实例的字段.这些代表着大多数可提交的数据库属性值的当前状态.
如果用户所有attribute都没有标记成Change Indicator属性,这种情况
我们将只比较单一的indicator属性值.然后我们比较在锁住期间选择的
attribute (来自EO),最初时用户选择的那些行,这些最初的值是相同的.如果在
锁住期间选的attribute和最初的值不同则会弹出此异常
下面有五种原因会发生此类异常
1.用户持有出发器改变了EO列,但在BC4J上没有选择 "Refresh on
Insert"或"Refresh on Update"
2.用户的数据表存在父子级关系,但在BC4J上没有选择"Refresh on
Insert"或"Refresh on Update"
3.用户创建了Expert Mode 模式的 Sql statementVO,并且得到的自定义sql与VO
字段不一致
4.用户所使用的字段是个自定义的class,并且没有实现自定义class的equals方
法
5.用户使用了rowid属性在EO中但并没标记成"Refresh on Insert" and
"Refresh on Update".一些数据库的功能,像分区可能会导致ROWID值行数据更
新时进行更新
在第一和第二的情况下,适当地设置刷新标志为触发器改变任何相关的实体对象
的属性
第三个情况中,双检查您的自定义的SQL语句是不小心选择到你的视图对象属性
错列的值不经意间,并参观“属性映射”面板来验证,选择列表,以查看对象的
属性映射是他们应。
第四个情况,依赖于你的域类“能够比较同一类的另一个实例本身的,所以你需
要实施正确运作的equals()为您的自定义域类的方法。
在第五种的情况下,只是标记表示的属性标志,以避免该问题。