确定。我有一种情况,我有两家公司,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行。
有什么想法?我相信这并不难,但我有问题,哈哈。谢谢!
答案 0 :(得分:0)
所以你需要的是:
这些事情只是在我的脑海中发挥作用。我一直在尝试一些像'select for update nowait'这样的东西,但它不起作用。可能是因为一旦块被运行,锁就会被释放。
我希望我能通过谷歌找到一些东西,但真的没有快乐。我自己没有遇到过这个要求(但是?),所以我对如何最好地解决这个问题感到有点难过。
编辑:我记得我在过去5年里曾在某处使用过dbms_locks,也许你应该尝试一下。 DBMS_LOCK不能在apex.oracle.com上使用,但我在我的数据库中没有权限(并且dba不在这里)。所以请继续查看DBMS_LOCK和this 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非法锁定手柄
我喜欢扩展顶点,但是如果你不得不为了这一页只有一页,并且有许多不同的流程,那么这一页的所有自定义...也许有一个简单的方法,我我自己也看不到它。