java - 客户端异常关闭时Oracle Activity session 状态

标签 java oracle jdbc session-timeout

好时光。

几天前,我们的数据库团队检测到,有一些客户端的 session 处于“Activity ”状态,但不再 Activity 。调查显示,此类问题主要有两个来源:

  1. 远程 SQL Developer 连接(实际上,这个案例并不是很有趣),
  2. tomcat(运行我们的应用程序的地方)异常关闭(如“kill -9”)

对我来说很奇怪的是所有 session 都处于“Activity ”状态。请有人澄清一下这是怎么回事(也许有一些底层进程在相应的套接字上等待,或者......只要正确关闭 tomcat 后一切正常,似乎根本原因是事务。 ..)?

如果我们设置“IDLE_TIME”(针对所有连接)和“EXPIRE_TIME”(针对所有 RAC 实例)会有帮助吗?

我是否正确,应该发生以下场景(设置上述参数):

  1. 当客户端连接时,其 session 被标记为“ACTIVE”
  2. 无论“ACTIVE”状态如何,都会有一个由“EXPIRE_TIME”参数发起的“ping”过程,用于对客户端执行 ping 操作。
  3. 如果 ping 进程在 EXPIRE_TIME 时间段内失败,即使 session 处于“ACTIVE”状态,该 session 也会被 Oracle 终止。
  4. 如果客户端响应 ping,但不执行任何处理,则在 IDLE_TIME 时间段后,其 session 将变为“INACTIVE”,并且(如果设置了“IDLE_TIME”参数)一段时间后 -“SNIPED”。之后,“SMON”进程会为此 session (以及其他具有“SNIPED”状态的 session )启动内务处理 Activity 。

更新:

解决这种情况的唯一方法似乎是配置 Oracle 实例。 我的调查结果如下:

  • https://community.oracle.com/thread/873226?start=0&tstart=0

    For Dead Connection Detection is used server side sqlnet.ora file parameter SQLNET.EXPIRE_TIME= <# of minutes>

    The other option would be implement idle_time in profile setting. And then with some job kill SNIPED sessions (when idle_time will be reached, session will become from INACTIVE to SNIPED).


    If I open up a connection and go off to lunch, an IDLE_TIME limit will cause my session to be terminated after 15 minutes of inactivity. An EXPIRE_TIME of 15 minutes will merely have Oracle send a packet to my client application to verify that the client has not failed. If the client is up, it will answer the ping, and my session will stay around indefinitely. EXPIRE_TIME only causes sessions to be killed if the client application fails to respond to the ping, implying that the client process has failed or that the client system has failed. IDLE_TIME will kill sessions that don't have activity for a period of time, but that generally doesn't work well with applications that maintain a connection pool, since the assumption there is that the connection pool will have a fair number of connections that are idle for periods of the day and since applications that use connection pools tend to react poorly to connections in the pool getting killed.

  • https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2233109200346833212

    TCP/IP doesn't interrupt things by default, by design. When a connection goes away, the client and/or server do not immediately get notified. So, if your client connects to the database and does nothing and you unplug your client (blue screen it, kill it, pull out the network cable, crash the computer, whatever) the odds are the session will stay in the database. The server will not know that it will never receive a message from you. We have dead client detection for that if it becomes an issue:

    http://download.oracle.com/docs/cd/B12037_01/network.101/b10776/sqlnet.htm#sthref476

    As for the active session, that is really easy. You open a connection, you submit a request over this connection like "lock table T". Table t is locked by your transaction in your session. You then submit a block of code like:

    begin loop dbms_lock.sleep(5); end loop; end; /

    your session will be active for as long as that code is running - the client process is blocked on a socket read waiting for the server to send back a result - a response (which of course will never come). The server isn't touching the network at all right now - it is active with your code. So, if your client 'dies' right now - the block of code will continue to run, and run, and run - and since it never commits - it'll just hang in there and run and of course any locks you have will remain in place.

  • http://www.databaseskill.com/4267817/

  • http://www.dba-oracle.com/t_connect_time_idle_expire_timeout.htm

    The sqlnet.expire_time parameter is used to set a time interval, in minutes, to determine how often a probe should be sent verifying that client/server connections are active. If you need to ensure that connections are not left open indefinitely (or up to the time set by operating system-specific parameters), you should set a value that is greater than 0. This protects the system from connections left open due to an abnormal client termination.

  • https://asktom.oracle.com/pls/apex/f?p=100:11:0::NO::P11_QUESTION_ID:453256655431

    If the session is waiting for a resource locks or latches, and if this wait time exceeds idle_time setting in th profile, does the session gets sniped, even if the session is in the middle of a transaction and waiting for lock etc.

    If so, will there be any entries in the alert log.

    Followup

    if waiting for a lock, you are active -- not idle.


    These page get my attention, six month before I had an Oracle Support for a Data Guard issue, so one of the Oracle guys, notice that I use the Idle_Time and he told me that this parameter dont work very well because Oracle dont release the resource of sessions that were marked as snipped, until the next time the user try to use it (waiting to tell your session was killed, to clear the session resources)

    Followup

    ... after an investigation... the "session" is there, that will not go away until the client acknowledges it, but the "transaction" is gone.


    Tom, I've altered a profile to have IDLE_TIME=240(4 hours) and made sure my resource_limit parameter is set to TRUE. When I query v$session I see some "snipped" sessions, but also "inactive" ones that have been idle for more than a day. All those users have this profile assigned to them. If the user session was connected before idle_time was set, would those sessions be affected by this change or not? I've made a change quite some time ago. Is there anything else I should have done?

    Followup

    If the user session was connected before idle_time was set, they are "grandfathered" in -- they will not be sniped. it only affects new sessions.

  • http://agstamy.blogspot.ru/2011/03/profile-and-resource-limit.html

  • 其他内容和建议:https://rebby.com/blog.php?detail=32

最佳答案

我们已经检查了上述调查中列出的参数,一切正常!

关于java - 客户端异常关闭时Oracle Activity session 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23636814/

相关文章:

java - 当键盘处于 Activity 状态时,停止调整 ListView 的大小。[带图像]。安卓工作室

java - 我可以让一个类只有方法吗?

java - 查询被触发但插入未反射(reflect)在数据库中

Java preparedstatement 比 sql developer 慢

java - 使用 JDBC 连接到 Athena 时找不到合适的驱动程序

javascript - 如何通过检查元素找到文件的位置?

java - 在数组中查找一定数量的相邻条目

java - 使用多个输出参数调用 Oracle StoredProcedure

sql - 数字乘以常数会得到负数

java - 如何在 JDBC 中映射 Oracle 对象