Oracle APEX - 选择要在表单提交时使用进程插入的下一行

时间:2012-01-12 20:41:51

标签: sql oracle process oracle-apex

确定。我有一种情况,我有两家公司,COMPANY1和COMPANY2,它们协同工作以创建PART。由于他们一起工作,他们都拥有所有权,因此他们希望将PART_NUMBER分配给同一部分。 COMPANY1为COMPANY2提供了一个PART_NUMBERS块,用于分配他们创建的部分。

我有一个表(TABLE_PARTS),其中包含主键(COMPANY1_PART_NUMBER)。由于COMPANY1为COMPANY2提供了一个数字块,因此表格中只填入了这些数字,等待分配到实际部分。

我有一个输入表格,供COMPANY2用来插入零件信息,包括COMPANY2_PART_NUMBER。我需要更新TABLE_PARTS中的行以填充pk,COMPANY1_PART_NUMBER周围的其余列,从而将该数字分配给零件。

我已确定需要选择MIN(COMPANY1_PART_NUMBER),其中COMPANY2_PART_NUMBER为空,并使用部件信息更新该行。

我需要确定在提交表单后将使用进程更新哪一行,因为表单将有并发用户,并且当页面加载时选择一行肯定会导致人们意外地尝试插入相同的COMPANY1_PART_NUMBER行。

有什么想法?我相信这并不难,但我有问题,哈哈。谢谢!

1 个答案:

答案 0 :(得分:0)

所以你需要的是:

  • 一个且只有一个用户可以在页面的某个位置拥有某个免费部件ID。不允许用户打开表单并让他们填写详细信息,然后在提交页面后使进程失败,例如,由于其他用户已经使用了该号码。
  • 这已经排除了apex中使用的标准机制。并发和丢失更新检查仅发生在DML处理点,通常在计算和验证后提交。
  • 我正在考虑标记用户选择进行更新的行。但是,这也必须撤消。只要用户实际单击“取消”按钮,就可以了,但如果没有额外的框架,则无法捕获其他事件。即使这样,您也只能捕获浏览器事件。如果用户击落浏览器进程甚至崩溃,标记记录会发生什么!?它只会坐在那里,等待开发人员解决这个问题,或者没有意识到他们从未实际用完数字。
  • 也许有可能编写一个自己的锁定机制:创建一个锁定页面上载。在选择的部件ID后命名此锁,以便可以检查它。此页面上的另一个onload进程应该检查输入id的锁定。如果存在锁定,则失败并执行某些操作,例如重定向。创建的锁也可以被赋予超时,因此这实际上会为崩溃的浏览器和计算机提供备份。然后,当用户取消操作时,您需要删除此锁定。单击通过面包屑或导航仍然没有被捕获,但您可以依赖锁定超时。或者在退出之前使用框架扩展,例如Skillbuilders保存。然后,您可以使用页面进程删除不同退出事件上的锁定(通过ajax调用)。尽管如此,解决方案仍然不是100%最佳。一个例子是只剩下1条记录,而用户想要分配一些东西。但是,由于某种原因,锁仍然会超时,因此用户会收到错误消息,因此导致认为没有留下任何ID。同样,这可以通过提供更详细的错误消息来解决,说明还有数字但当前已被锁定(“稍后再试一次”? - : - /)

这些事情只是在我的脑海中发挥作用。我一直在尝试一些像'select for update nowait'这样的东西,但它不起作用。可能是因为一旦块被运行,锁就会被释放。

我希望我能通过谷歌找到一些东西,但真的没有快乐。我自己没有遇到过这个要求(但是?),所以我对如何最好地解决这个问题感到有点难过。

编辑:我记得我在过去5年里曾在某处使用过dbms_locks,也许你应该尝试一下。 DBMS_LOCK不能在apex.oracle.com上使用,但我在我的数据库中没有权限(并且dba不在这里)。所以请继续查看DBMS_LOCKthis example

你要做的是:创建一个onload-after标头进程,并在那里创建一个独占锁(独占,当然你不想分享任何东西)。您希望此ID对于所选的部件ID是唯一的。确保锁定超时(默认为MAXWAIT =永远!)或者有一个取消进程以释放锁定,因此您不会在测试时遇到麻烦。

-- this is just a handle though, not the actual lock
dbms_lock.allocate_unique(lockname        => 'lock_part_'||company1_part_id,
                          lockhandle      => v_lockhandle, 
                          expiration_secs => 300 -- 5 mins
                         ); 

-- request does the actual lock,
-- so this'll give errors when called for the same lockhandle 
-- and a lock is already in effect
v_result := dbms_lock.request(lockhandle => v_lockhandle, 
                              lockmode => dbms_lock.x_mode, 
                              timeout => 0 -- fail instantly and don't wait to put a lock if already locked,
                              release_on_commit => true/false -- try both, not sure if it'll work with TRUE
                             );
  

release_on_commit
  将此参数设置为TRUE以释放锁定   提交或回滚。

     

否则,锁定将一直保持到明确释放或直到锁定为止   会议结束。

如果情况良好,由于您创建的锁定,另一个会话将无法锁定相同的ID。捕获错误您必须自己尝试,但不应该对现有锁进行硬性测试并为错误提供足够的反馈。

  

DBMS_LOCK.request   返回值

     

表70-10 REQUEST函数返回值

     

返回值说明
  0成功
  1超时
  2死锁
  3参数错误
  4已经由id或lockhandle指定的锁定   5非法锁定手柄

我喜欢扩展顶点,但是如果你不得不为了这一页只有一页,并且有许多不同的流程,那么这一页的所有自定义...也许有一个简单的方法,我我自己也看不到它。