2015-03-03 69 views
0

我的问题与this one非常相似,但我需要更多指导。我还阅读了Oracle context文档。参数化触发器 - 并发问题

目前(测试)触发:

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应用程序的用户,这些值需要从应用程序传递。

Web应用程序:

  1. 被部署在WebSphere Application Server在数据源配置
  2. 正如预期的那样,是使用数据库连接池

我的问题是哪种方法中提到的线程和文档。我应该采取什么措施来避免“并发”问题,即应用程序的更新。在应用程序级别的多个会话中的用户以及数据库级别不应相互干扰。

+0

你可能要“砍”休眠不知何故,迫使某种每次启动新事务时执行回调,或每次从池中取消连接时执行回调。我怀疑这甚至是可能的。 – ibre5041 2015-03-03 14:27:09

回答

0

我不认为该链接中的任何一种方法都适用于您,主要是由于多用户环境和连接池。

本质上的连接池允许不同的连接共享相同的会话。设置上下文(sys_context或任何其他应用程序上下文)在会话的整个生命周期内都是有效的。因此,两个不同的连接可以覆盖彼此的值并读取其他值。 (并发问题)

我实际上会反对在触发器中插入这样的内容。在我看来,你正在做的插入操作是向日志表写入主表上发生的所有更新。如果是这种情况,为什么在对此表进行更新时不插入日志表。

因此,UPDATE CHASSITRANSPORTS ...的程序在其中还会有另一个INSERT语句写入另一个表。如果没有过程,并且它是来自应用程序的直接更新语句,则为此写入一个过程。

你可以说有多个地方发生了同样的更新,我建议在这种情况下为基表CHASSITRANSPORTS创建一个处理更新的API,因此黑盒子后面也会写入日志表。任何需要更新表格列的地方都会使用该API。

(我不理你是抑制触发所有的错误与WHEN OTHERS THEN NULL与希望,这可能只是一个小例子事实)

+0

我有点困惑'根据自然的连接池允许不同的连接共享同一个会话',还是多个会话可以共享一个连接?无论如何,将两个不同的网络应用程序。会话会覆盖彼此的值,以防他们使用相同的数据库。康涅狄格州。从游泳池? – 2015-03-03 14:42:33

+0

来自应用程序的多个连接在池中共享相同的会话。连接池的主要原因是减少打开和关闭新会话所需的时间。 – ruudvan 2015-03-03 14:46:04

+0

@KaliyugAntagonist是的,上下文值通过oracle会话有效。来自应用程序的多个连接可能已通过该池连接到同一会话并访问了前一个会话的上下文值。测试非常简单。创建一个只连接数据库并使用'SELECT SYS_CONTEXT('USERENV','SID')FROM DUAL'打印会话ID的小应用程序。您应该看到连接共享同一个池中的同一个会话。 – ruudvan 2015-03-03 14:49:07