Oracle ODP.NET连接池
数据库连接池
连接池是数据库连接的缓存,每当应用程序需要连接数据库时向连接池申请数据库连接,连接池负责具体数据库连接的创建和销毁。连接池中的数据库连接会缓存一段时间,后续的连接请求首先使用缓存中的数据库连接,如果缓存中有空闲的连接则直接使用,无空闲连接时就去新创建。这样可以提高因数据库连接创建而额外消耗的资源,从而提高整体性能。
.NET连接Oracle
.NET连接Oracle数据库的库主要有3种:
- .NET自带的 .NET Framework Data Provider for Oracle
- Devart提供的dotConnect for Oracle
- Oracle提供的 Oracle Data Provider for .NET / ODP.NET
目前xAsset系统使用的是第3种,由Oracle提供的ODP.NET。ODP.NET提供了一套实现了ADO.NET相关接口的类,并提供了使用Oracle数据库一些高级功能的接口,比如RAC,XML DB,批量插入等。相对于.NET自带的库性能上也提高不少。
ODP.NET现在是Oracle ODAC(Oracle Data Access Component)的一部分。使用前需要先安装ODAC组件,Oracle提供了xcopy的方式和可执行程序的方式供下载安装。具体安装方法见官方文档。
ODP.NET的数据库连接字符串格式主要有以下几种:
- 使用TNS
该方式需要配置TNS,一般需要提供用户id和密码(集成认证方式可以省略用户id和密码)。具体的字符串格式如下:
Data Source=TORCL;User Id=myUsername;Password=myPassword;
- 不依赖tnsnames.ora的ODP.NET方式
该方式不需要配置TNS,以把配置在TNS里的连接字符串直接放到Data Source节点中的方式实现。连接字符串中直接提供了服务器地址,端口,实例等信息,具体格式如下:
Data Source=(DESCRIPTION=(ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=MyHost) (PORT=MyPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=MyOracleSID)));
User Id=myUsername;Password=myPassword;
- 使用EZ Connect的方式
使用EZ Connect方式也不需要进行特殊配置,但需要数据库服务中的sqlnet.ora启用该方式,添加NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)启用,具体连接字符串格式如下:
Data Source=username/password@myserver//instancename;
ODP.NET的连接池及相关功能
ODP.NET提供了连接池的功能。当然我们可以选择使用或不使用,是否启用连接池功能由数据库连接字符串决定。连接参数提供了Pooling这个参数,如果值为true则启用连接池,否则不启用,不提供该参数时默认是启用连接池的。
数据库连接参数中除了上面提到的标准参数Data Source,User Id,Password外,与连接池相关的参数主要有几个:Connection Lifetime, Connection Timeout, Decr Pool Size, Incr Pool Size, Max Pool Size, Min Pool Size, Pooling, Validate Connection。
当启用连接池时,取得一个数据库连接的过程大致如下:
l 如果连接池不存在(比如应用程序刚启动第一次访问数据库),则ODP.NET创建连接池并按参数“Min Pool Size”设置的值(默认1)初始化数据库连接。这个值指定了连接池中的最小连接数量,无论如何连接池中至少有该值设定的数据库连接存在。直到连接池销毁。
l 如果连接池存在,则检查是否有可用连接。
u 如果有可用连接,连接就从池中取出返回给应用程序。
n 如果启用了“Validate Connection”,则连接池会去数据库服务器验证当然连接是否有效。
u 如果没有可用连接,连接池会检查当前池中的连接数是否已达到指定的上限“Max Pool Size”(默认100)。
n 如果已经达到最大上限,则请求会等待一段“Connection Timeout”(默认15秒)指定的时间,检查是否这段时间内有连接返回到池中。
- 如果有连接返回到池中,则直接取该连接返回给请求的应用程序。
- 如果指定时间内仍没有连接可用,则抛出“Connection request timed out”异常。
n 如果还没达到上限,则连接池会主动创建“Incr Pool Size”(默认5)指定的值的连接,并返回其中一个给请求的应用程序。
当应用程序从数据库取得数据并调用Close()/Dispose()时,连接池检查连接的生命同期是否超过了“Connection Lifetime”(默认0,不检查)。
如果连接的生命周期超过了定义的值,则该连接会被真正关闭。这个关闭,指应用程序所在连接池到数据库服务器的物理连接关闭。
连接只有返回到池中时才会做该检查,如果在使用中不会检查。
当然如果连接真正关闭后池中的连接数量会小于“Min Pool Size”指定的值时,连接也不会关闭。
连接池每隔3分钟会关闭池中没有使用的连接,每次关闭的数量由“Decr Pool Size”设定的值(默认1)指定。