理解oracle中连接和会话

来源:互联网 发布:威士忌用什么杯子 知乎 编辑:程序博客网 时间:2024/04/19 11:37

比喻:

一个物理连接相当于一条现代化超安全的高速公路,

每个会话(jdbc connection)相当于该公路上100%遵守交通秩序的车辆。

一个会话中的提交不会影响该连接上的任何其他会话。

实际上,一条连接上的各个会话可以使用不同的用户身份!

另外,一个会话可以有连接也可以没有连接,相当于这辆车停在车库,并没有行驶到公路上,这时它是空闲的,

当行驶到公路上,就相当于给它建立了一个物理连接

 

相关图书:Oracle Database 10g安全性高效设计

 

隐式连接缓冲:通过创建真正的数据库物理连接的逻辑映射来完成连接池的管理工作,在应用程序中关闭连接池的连接并不会断开物理连接,而是把逻辑连接归还给连接池,并可用于下次请求。结论(隐式连接缓冲建立的连接都是物理连接)

在weblogic中选择了驱程的类别后,实际上要看我们采用的oracle驱动,其中负责隐式连接缓冲的驱动位于/%ORACLE_HOME%/jdbc/lib/classes12.jar

 

 

 

连接并不是会话的同义词,发现这一点时很多人都很诧异。在大多数人眼里,它们都是一样的,但事实上并不一定如此。在一条连接上可以建立0个、一个或多个会话。各个会话是单独而且独立的,即使它们共享同一条数据库物理连接也是如此。一个会话中的提交不会影响该连接上的任何其他会话。实际上,一条连接上的各个会话可以使用不同的用户身份!

在Oracle中,连接只是客户进程和数据库实例之间的一条特殊线路,最常见的就是网络连接。这条连接可能连接到一个专用服务器进程,也可能连接到调度器。如前所述,连接上可以有0个或多个会话,这说明可以有连接而无相应的会话。另外,一个会话可以有连接也可以没有连接。使用高级Oracle Net特性(如连接池)时,客户可以删除一条物理连接,而会话依然保留(但是会话会空闲)。客户在这个会话上执行某个操作时,它会重新建立物理连接。下面更详细地定义这些术语:
* 连接(connection):连接是从客户到Oracle实例的一条物理路径。连接可以在网络上建立,或者通过IPC机制建立。通常会在客户进程与一个专用服务器或一个调度器之间建立连接。不过,如果使用Oracle的连接管理器(Connection Manager ,CMAN),还可以在客户和CMAN之间以及CMAN和数据库之间建立连接。CMAN的介绍超出了本书的范围,不过Oracle Net Services Administrator’s Guide(可以从http://otn.oracle.com免费得到)对CMAN有详细的说明。
* 会话(session):会话是实例中存在的一个逻辑实体。这就是你的会话状态(session state),也就是表示特定会话的一组内存中的数据结构。提到“数据库连接”时,大多数人首先想到的就是“会话”。你要在服务器中的会话上执行SQL、提交事务和运行存储过程。

可以使用SQL*Plus来看一看实际的连接和会话是什么样子,从中还可以了解到,实际上一条连接有多个会话的情况相当常见。这里使用了AUTOTRACE命令,并发现有两个会话。我们在一条连接上使用一个进程创建了两个会话。以下是其中的第一个会话:
sqlplus "storm/unimas"
SQL> select username, sid, serial#, server, paddr, status from v$session where username = 'STORM';
USERNAME      SID    SERIAL# SERVER    PADDR STATUS
------------------------------ ---------- ---------- --------- -------- --------
STORM      148  60 DEDICATED 30A1BDCC INACTIVE

SQL> set autotrace on statistics
SP2-0618: Cannot find the Session Identifier.  Check PLUSTRACE role is enabled
SP2-0611: Error enabling STATISTICS report
SQL>

碰到错误,原来是没有添加PLUSTRACE role
sqlplus "sys/unimas as sysdba"
SQL> create role plustrace;
Role created.
SQL> grant select on v_$sesstat to plustrace;
Grant succeeded.
SQL> grant select on v_$statname to plustrace;
Grant succeeded.
SQL> grant select on v_$mystat to plustrace;
Grant succeeded.
SQL> grant plustrace to dba with admin option;
Grant succeeded.
SQL> grant plustrace to STORM;
Grant succeeded.

重新登录storm
SQL> set autotrace on statistics

USERNAME      SID    SERIAL# SERVER    PADDR STATUS
------------------------------ ---------- ---------- --------- -------- --------
STORM      141 180 DEDICATED 30A1BDCC INACTIVE
STORM      148  62 DEDICATED 30A1BDCC INACTIVE

SQL> disconnect

从技术上讲,这个命令应该叫DESTROY_ALL_SESSIONS更合适,而不是DISCONNECT,因为我们并没有真正物理地断开连接。

在SQL*Plus中要真正地断开连接,应该执行“exit”命令,因为你必须退出才能完全撤销连接。

SQL> select username, sid, serial#, server, paddr, status from v$session where username = 'STORM';
no rows selected

可以看到,这个账户名下没有会话,但是仍有一个进程,相应地有一条物理连接(使用前面的ADDR值)

SQL> select username, program from v$process where addr = hextoraw('30A1BDCC');

USERNAME PROGRAM
--------------- ------------------------------------------------
oracle oracle@hb (TNS V1-V3)

SQL> 
所以,这就有了一条没有相关会话的“连接”。可以使用SQL*Plus的CONNECT命令(这个命令的名字也起得不恰当),在这个现有的进程中创建一个新会话(CONNECT命令叫CREATE_SESSION更合适):可以看到,这个账户名下没有会话,但是仍有一个进程,相应地有一条物理连接(使用前面的ADDR值)
SQL> select username, sid, serial#, server, paddr, status from v$session where username = 'STORM';

USERNAME      SID    SERIAL# SERVER    PADDR STATUS
------------------------------ ---------- ---------- --------- -------- --------
STORM      153  58 DEDICATED 30A1BDCC INACTIVE

可以注意到,PADDR还是一样的,所以我们还是在使用同一条物理连接,但是(可能)有一个不同的SID。我说“可能有”,是因为也许还会分配同样的SID,这取决于在我们注销时是否有别人登录,以及我们原来的SID是否可用。

另外:
Serial# is in v$session. It is an Oracle generated value used in
combination with the SID to create a unique session identifier.
SID和SERIAL合起来能作为一个session的唯一标识。

1.       概念不同:

连接是指物理的客 户端到oracle服务端的连接。一般是通过一个网络的连接。

在已建立的连接 上,建立客户端与oracle 的会话,以后客 户端与oracle 的交互都在一个会话环境中 进行。

2.   关系是多对多:[同意网友的意见,应该是1对 多。一个会话要么没有连接,要么在一个连接上。]

一个连接上可以建 立0 个,1 个,2 个,多个会话。

Oracle 允许存在这样的会话,就是失去了物理连接的会 话。

3.       概念应用:

l         oracle sessions 参数决定的是会话数而不是物理连接数。

l         oracle 的临时表中的数据是各会话间隔离的,而与连接 概念无关。

l         jdbc connection ,对oracle 是一个会话的概念。

4.     实际应用:

连接 池,为了提高数据库交互效率,一般驱动程序都有连接池概念的实现。

      Oracle 不同的驱动提供两种连接池概念。

一种译 为隐式连接缓冲

OracleDataSource ods = new OracleDataSource();

            ods.setURL( "jdbc:oracle:thin:@10.1.3.60:1521:orcl" );

            ods.setUser( "NC50_DEV" );

            ods.setPassword( "NC50_DEV" );

            ods.setConnectionCachingEnabled( true );

          java.util.Properties jup = new java.util.Properties();

            jup.setProperty( "InitialLimit" , "1" );

            jup.setProperty( "MinLimit" , "1" );

            jup.setProperty( "MaxLimit" , "2" );

            ods.setConnectionCacheProperties(jup);

           Connection cx0 = ods.getConnection();

      隐式连接缓冲在第一次getconnection ()时将根据配置初始化连接,并在每一个连接上建立一个会话。然后从这些会话中返回一个给本次 调用。以后如果在本次connection.close() 前 调用getconnection (),将肯定 得到另外一个会话。如果初始时建立的会话不够了,那么将新建物理连接,并在连接上建立一个会话。当然不能超过两个限制:1.MaxLimit 【见程序,限制物理连接数】。

2.sessions oracle 参数】。每次close() 并不关闭实际的会话,而是返回连接缓冲中, 供另一个getconnection() 使 用。所以可以得知,如果一个getconnection() 中 给某一个会话级临时表插入数据,然后close(), 那 么之后如果这个会话被重新得到,是可以看到插入的数据的。

一种译 为OCI 连接池。

OracleOCIConnectionPool ods = new OracleOCIConnectionPool();

            String tns = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS="

                    + "(PROTOCOL=TCP)(HOST=10.1.3.60)(PORT=1521)))"

                    + "(CONNECT_DATA=(SERVICE_NAME=ORCL)))" ;

            ods.setURL( "jdbc:oracle:oci:@" + tns);

            ods.setUser( "NC50_DEV" );

            ods.setPassword( "NC50_DEV" );

            java.util.Properties jup = new java.util.Properties();

    jup.setProperty(OracleOCIConnectionPool. CONNPOOL_MIN_LIMIT , "2" );       jup.setProperty(OracleOCIConnectionPool. CONNPOOL_MAX_LIMIT , "2" );

    jup.setProperty(OracleOCIConnectionPool. CONNPOOL_INCREMENT , "0" );

            ods.setPoolConfig(jup);

        Connection cx0 = ods.getConnection();

            OCI 连接池在第一次getconnection () 时将根据配置初始化连接,并在每一个连接上建立一个会话。注意,连接上一旦建立了一个会话,这个连接将还可以再建会话。那么在此时,会任取一个建完会话的 物理连接再建一个会话返回。这样看来似乎OCI连接池只需建立一个物理连接就可以建立任意多的会话,当然这时也要受限于oracle允许的sessions 设置。实际上OCI到底1个物理连接对应 多少个会话,OCI自身有一个对应用透明的管理。但是CONNPOOL_MAX_LIMIT 一定是限制住此客户端可用的物理连接数的。对于OCI 连接池,每一个connection.close() 都将实际关闭会话, 但物理连接保留。所以可以得知,如果一个getconnection() 中 给某一个会话级临时表插入数据,然后close(), 那 么此数据将被删除。

5 . 关于专用服务器模式下processes 参数

            对于隐式连接缓冲,每一个连接上建立一个会话,对于每一个会话都将对应一个dedicated process 

            对于OCI 连接池,只有物理 连接上建立的那个会话才对应一个dedicated process( 这里记为DP_A,DP_B) 。 而其他会话对应一个PSUEDO process. 这 是一个轻量级process ,它是不算processes 数的。

        所以关于这个问题“专用服务器模式是一个物理连接对应一个process ,还是一个会话对应一个process ?”,从这里可以理解oracle 的设计思路确实一个是会话对应一个process ,与物理连接不相关。但是实际的实现呢?当oci 获得的connection 上执行sql 时,ORCLED 的响应还是会借助到DP_A,DP_B 上,如果DP_A,DP_B 正忙,那就得一样地等。

补 充:
1.物理连接一般跟网络资源有关的。通过网络的一个物理连接会占用客户端一个新的临时端口。
2.JTA事务管理,是针对多个会话的 DB访问,维系在一个事务中。这个概念是多会话,而不是刻意强调多个数据源(两个ORACLE),甚至异种数据库。JDBC事务管理,是建立在一个会话上 的事务。
3.processes参数控制的是oracle所有进程/线程,不仅仅是专用server,包括后台普通进程,典型的如果在MTS模式 下,还包括dispatcher。而OCI下连接PSUEDO process的作用有点类似MTS模式下的dispatcher,但它不受processes限制。同时注意即使有这个PSUEDO process 存在,专用模式和MTS还是 截然不同,因为专用模式下必须等到DP_A,DP_B 的 客户会话关闭后才可用DP_A,DP_B 来服 务PSUEDO process 对应的客户会 话,而MTS是不等会话结束就拉过来服务了。 
官方解释 

1.1 connection:
   A connection is a physical path from a client to an Oracle instance. A connection is established either over a network or over an IPC mechanism. A connection is typically between a client process and either a dedicated server or a dispatcher. However,using Oracle’s Connection Manager (CMAN), a connection may be between a client and CMAN, and CMAN and the database.
 
1.2 session
   A session is a logical entity that exists in the instance. It is your session state, or a collection of data structures in memory that represents your unique session. It is what would come first to most people’s minds when thinking of a “database connection.” It is your session in the server, where you execute SQL, commit transactions, and run stored procedures.
 
1.3 connection vs. session
   A connection may have zero, one, or more sessions established on it. Each session is separate and independent,even though they all share the same physical connection to the database. A commit in one session does not affect any other session on that connection. In fact, each session using that connection could use different user identities!
   In Oracle, a connection is simply a physical circuit between your client process and the database instance—a network connection, most commonly. The connection may be to a dedicated server process or to a dispatcher. As previously stated, a connection may have zero or more sessions, meaning that a connection may exist with no corresponding sessions. Additionally, a session may or may not have a connection. Using advanced Oracle Net features such as connection pooling, a physical connection may be dropped by a client, leaving the session intact (but idle). When the client wants to perform some operation in that session, it would reestablish the physical connection.
原创粉丝点击