连接生命周期
ManagedConnection 对象总是处于以下三种状态之一:DoesNotExist、InFreePool 或 InUse。
创建连接前,它必须处于 DoesNotExist 状态。创建连接后,它可以处于 InUse 或 InFreePool 状态,取决于它是否已经分配到应用程序。
- 应用程序已经调用数据源或连接工厂 getConnection 方法(getConnection 条件)
- 池中存在属性匹配的空闲连接(freeConnectionAvailable 条件)
- 并且以下两个条件之一为真:
- getConnection() 请求代表标记为不可共享的资源引用
- getConnection() 请求代表标记为可共享的资源引用,但使用中的可共享连接没有相同的属性。
InFreePool > InUse: getConnection AND freeConnectionAvailable AND NOT(shareableConnectionAvailable)这里是警戒条件和描述的列表。
条件 | 描述 |
---|---|
ageTimeoutExpired | 连接的寿命比它的 ageTimeout 值长。 |
close | 应用程序对 Connection 对象调用 close 方法。 |
fatalErrorNotification | 连接刚遇到致命错误。 |
freeConnectionAvailable | 空闲池中存在属性匹配的连接。 |
getConnection | 应用程序调用数据源或连接工厂对象上的 getConnection 方法。 |
markedStale | 连接会标记为失效,通常响应致命错误通知。 |
noOtherReferences | 仅有一个受管连接的连接句柄,事务服务并不保留受管连接的引用。 |
noTx | 没有有效事务。 |
poolSizeGTMin | 连接池大小大于最小池大小(最小连接数) |
poolSizeLTMax | 池大小小于最大池大小(最大连接数) |
shareableConnectionAvailable | getConnection() 请求的是可共享连接,属性匹配的连接正在使用,可供共享。 |
TxEnds | 已经结束事务。 |
unshareableConnectionRequest | getConnection() 请求的是不可共享连接。 |
unusedTimeoutExpired | 连接在空闲池中,并且未使用时间超过了它的“未使用超时”值。 |
获取连接
第一组转换发生在应用程序请求数据源或连接工厂连接时。其中某些情况会产生到数据库的新连接。在其他情况中,可从连接池获取连接或与连接的另一个请求共享连接。getConnection AND NOT(freeConnectionAvailable) AND poolSizeLTMax AND (NOT(shareableConnectionAvailable) OR unshareableConnectionRequest)
- 应用程序在数据源或连接工厂上调用 getConnection() 方法
- 空闲池中没有可使用的连接 (NOT(freeConnectionAvailable))
- 池大小小于最大池大小 (poolSizeLTMax)
- 如果请求的是可共享连接,但没有具有相同共享属性的可共享连接在使用 (NOT(shareableConnectionAvailable)),或者请求的是不可共享连接 (unshareableConnectionRequest)
所有连接以 DoesNotExist 状态开始,并仅在应用程序请求时创建。随着应用程序继续请求新连接,池大小从 0 增长到最大连接数。服务器启动时,并不创建最小连接数的池。
如果请求的是可共享连接,而应用程序已在使用具有相同共享属性的连接,那么此连接将由两个或两个以上的连接请求共享。在这种情况下,不创建新的连接。对于 JDBC API 用户,最常用的共享属性是用户标识/密码和事务上下文;而对于资源适配器公共客户机接口 (CCI) 用户,典型的共享属性连接规范、主体集和事务上下文。
InFreePool>InUse: getConnection AND freeConnectionAvailable AND (unshareableConnectionRequest OR NOT(shareableConnectionAvailable))
- 应用程序发出 getConnection() 调用
- 连接池中有可用的连接 (freeConnectionAvailable)
- 并且以下条件之一为真:
- 请求的是不可共享连接 (unsharableConnectionRequest)
- 事务中尚未使用具有相同共享属性的连接。(NOT(sharableConnectionAvailable))。
只要空闲池中的连接能满足任何连接请求,连接请求就不会产生新的数据库连接。因此,如果同一时刻任何个数的应用程序使用池中连接的数目从未超过 1,池大小增长决不会超过 1。这个数可以小于指定的池最小连接数。如果应用程序有多个必须新建连接的并行连接请求,那么池会增长到最小连接数。
InUse>InUse: getConnection AND ShareableConnectionAvailable
此转换表明如果应用程序请求一个可共享连接 (getConnection),而该连接的共享属性与已在使用的连接 (ShareableConnectionAvailable) 的共享属性相同,那么共享现有连接。
返回连接
前面讨论到的所有转换都涉及获取连接以供应用程序使用。出于此目的,转换将导致连接关闭,并返回到空闲池或被销毁。应用程序应该通过对连接对象调用 close() 显式关闭连接(注:用户取回的连接实际上是连接句柄)。在大多数情况下,此操作导致以下转换:InUse>InFreePool: (close AND noOtherReferences AND NoTx AND UnshareableConnection) OR (ShareableConnection AND TxEnds)
- 如果应用程序或容器调用 close()(形成关闭条件),并且没有应用程序(在应用程序共享条件下)或事务管理器(在 NoTx 条件下,意味着在事务中使用连接时,事务管理器持有引用)持有的引用(noOtherReferences 条件),那么连接对象将返回空闲池。
- 如果连接在事务中使用,而事务管理器结束了事务(txEnds 条件),此连接又是可共享连接(ShareableConnection 条件),那么连接关闭并返回到池。
当应用程序对连接调用 close() 时,它将连接返回到空闲连接的池;它不关闭到数据存储的连接。当应用程序对当前共享的连接调用 close() 时,连接不返回到空闲池。仅当应用程序断开最后的连接引用且事务结束后,连接才返回到池。使用不可共享连接的应用程序必须小心且适时地关闭连接。否则会抽空连接池,使服务器上运行的任何应用程序都不能获取连接。
当应用程序对事务中使用的连接调用 close() 时,连接不返回到空闲池。因为事务管理器还必须持有连接对象的引用,所以事务结束前,连接不能返回空闲池。一旦在一个事务中使用了连接,在此事务完成前,任何其他应用程序的任何其他事务中都不能使用该连接。
InUse>DoesNotExist: close AND markedStale AND NoTx AND noOtherReferences
此转换表明如果应用程序对连接调用了 close(),并且在池清除阶段将连接标记为失效连接 (markedStale),那么数据存储的连接对象关闭,并且不返回到池。
最后,您可以关闭到数据存储的连接并将其从池中移除。
- 如果从资源适配器(或数据源)接收到致命错误通知。发生某些情况使连接无法使用时,将从资源适配器接收到致命错误通知 (FatalErrorNotification)。空闲池中当前的所有连接都被销毁。
- 如果连接在空闲池中的时间比“未使用超时”周期 (UnusedTimeoutExpired) 长,并且池的大小比最小连接数大 (poolSizeGTMin),那么从空闲池移除并销毁连接。此机制使池能在对连接的需求减少时,缩回到其最小大小。
- 在配置了寿命超时,并且所指定连接的寿命比此超时长时。此机制提供了根据寿命回收连接的方法。