我的问题与this one非常相似,但我需要更多指导。我还阅读了Oracle context doc。
当前(测试)触发器是:
CREATE OR REPLACE TRIGGER CHASSIS_DT_EVNT_AIUR_TRG_OLD AFTER DELETE OR INSERT OR UPDATE
OF ETA
ON CHASSITRANSPORTS
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO TS_CHASSIS_DATE_EVENTS (CHASSISNUMBER,DATETYPE,TRANSPORTLEGSORTORDER,OLDDATE,CREATEDBY,CREATEDDATE,UPDATEDBY,UPDATEDDATE) VALUES (:old.chassino,'ETA',:old.sortorder,:old.eta,'xyz',sysdate,'xyz',sysdate);
EXCEPTION
WHEN OTHERS THEN
NULL;
END TS_CHASSIS_DT_EVNT_AIUR_TRG;
现在'CREATEDBY','UPDATEDBY'将成为已登录并进行导致触发器执行的更改的Web应用程序用户,因此,需要从应用程序传递这些值。
网络应用程序:
我的问题是线程和文档中提到的方法。我应该采取什么措施来避免“并发”问题,即应用程序的更新。应用程序级别的多个会话中的用户以及数据库级别不应相互干扰。
答案 0 :(得分:0)
我认为该链接中的任何一种方法都不适用于您,主要是由于多用户环境和连接池。
连接池本质上允许不同的连接共享同一会话。设置上下文(sys_context或任何其他应用程序上下文)在会话的整个生命周期内都有效。因此,两个不同的连接可以覆盖彼此的值并读取其他值。 (并发问题)
我实际上反对在触发器内完成这样的插入操作。在我看来,您正在执行的插入操作是将主表上发生的所有更新写入日志表。如果是这种情况,为什么不在对此表进行任何更新时插入日志表。
因此,UPDATE CHASSITRANSPORTS ...
的过程中还会有另一个INSERT
语句写入另一个表。如果没有过程并且它是来自应用程序的直接更新语句,那么为此编写一个过程。
你可以说有多个地方发生相同的更新,我建议在那个场景中为基表CHASSITRANSPORTS
创建一个处理更新的API,所以在黑盒子后面也会写到日志表。您需要更新该表列的任何地方,您都要使用该API。
(我忽略了你用WHEN OTHERS THEN NULL
抑制触发器中的所有错误的事实,希望这可能只是一个小例子)