yangtingkun在"一次ORA-942错误的跟踪(一)"中为了定位一个错误的产生原因,他用到了sql trace,但他所面临的系统用到了连接池,连接池会给定位要做trace的session带来困难。他在原文中也做了这样的描述"由于JAVA程序使用了连接池,导致一旦程序启动,就会有多个会话同时连接到数据库中,因此很难判断到底哪个会话会执行出错的SQL语句。当然可以修改程序,在运行出错的SQL前面运行ALTER SESSION SET SQL_TRACE = TRUE。但是还是由于连接池的特性,无法保证ALTER SESSION语句与随后的select语句在同一个会话上执行。随意修改程序的方法是行不通的。还有一个办法,就是修改中间件连接池,使得程序只有一个会话连接到Oracle数据库中。"
最后他用到的解决方法就是对所有连接池里的session都做trace,然后一个一个查看trace文件,最后来达到定位指定session的目的。
这实际上是一种穷举,要是后台连接池开了100个session,莫非你还要看100个trace文件?
太麻烦了!
他提到"随意修改程序的方法是行不通的",真的不行吗?当然可以!
答案就是用DBMS_SESSION.SET_IDENTIFIER。
修改代码,在执行sql前都先执行一下DBMS_SESSION.SET_IDENTIFIER就可以很方面的定位指定的session了,这个对连接池有效!并且这也是FGA针对的连接池的一种通常的解决方法。
Session 1:
SQL> conn caipra/acca@ipratest;
Connected to Oracle Database
Connected as caipra
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
---------- ---------- ----------
413 0 1
SQL> exec DBMS_SESSION.SET_IDENTIFIER ('CUIHUA');
PL/SQL procedure successfully completed
Session 2:
SQL> conn caipra/acca@ipratest;
Connected to Oracle Database
Connected as caipra
SQL> select sid,serial#,CLIENT_IDENTIFIER from v$session where CLIENT_IDENTIFIER = 'CUIHUA';
SID SERIAL# CLIENT_IDENTIFIER
---------- ---------- ----------------------------------------------------------------
413 14490 CUIHUA
Leave a comment