连接池的管理:
对 于 访问 量高的系 统 , 每 次 创 建一个 连 接都会消耗一定的 资 源,我 们 可以事先 创 建好一定数量的 连 接放入 连 接池中提供 给 用 户 使用,用 户 使用完后把 连 接返回 连 接池, 这 里我就来 说说连 接池的管理。
首先, 让 我 们 来看看 连 接池的概念:
1 。 连 接池允 许应 用程序从 连 接池中 获 得一个 连 接并使用 这 个 连 接,而不需要 为每 一个 连 接 请 求重新建立一个 连 接。一旦一个新的 连 接被 创 建并且放置在 连 接池中, 应 用程序就可以重 复 使用 这 个 连 接而不必 实 施整个数据 库连 接 创 建 过 程。
2 。当 应 用程序 请 求一个 连 接 时 , 连 接池 为该应 用程序分配一个 连 接而不是重新建立一个 连 接;当 应 用程序使用完 连 接后, 该连 接被 归还给连 接池而不是直接 释 放。
优 点:
1 。使用 连 接池的最主要的 优 点是性能。
2 。 创 建一个新的数据 库连 接所耗 费 的 时间 主要取决于网 络 的速度以及 应 用程序和数据 库 服 务 器的(网 络 )距离,而且 这 个 过 程通常是一个很耗 时 的 过 程。而采用数据 库连 接池后,数据 库连 接 请 求可以直接通 过连 接池 满 足而不需要 为该请 求重新 连 接、 认证 到数据 库 服 务 器, 这样 就 节 省了 时间 。
缺点:
1 。数据 库连 接池中可能存在着多个没有被使用的 连 接一直 连 接着数据 库 ( 这 意味着 资 源的浪 费 )。
ps : 这 必 须 要求 开发 人 员 在 开发时 估 计这 个系 统 最大提供的数量是多少。
池的 创 建和分配
当 连 接打 开时 ,将根据一 种 精确的匹配算法来 创 建 连 接池, 该 算法会使 连 接池与 连 接中的字符串相 关联 。 每 个 连 接池都与一个不同的 连 接字符串相 关联 。当新 连 接打 开时 ,如果 连 接字符串不精确匹配 现 有 池, 则 将 创 建一个新池。
在以下示例中,将 创 建三个新的 SqlConnection 对 象,但只需要使用两个 连 接池来管理 这 些 对 象。 请 注意,第一个和第二个 连 接字符串的差异在于 为 Initial Catalog 分配的 值 。
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// 连 接池 A 创 建了
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs";
conn.Open();
// 连 接池 B 创 建了,因 为 ConnectionString 与 A 不匹配
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// 使用 A 的 连 接池,因 为 ConnectionString 与 A 匹配
连 接池一旦 创 建,直到活 动进 程 终 止 时 才会被 毁 坏。 非活 动 或空池的 维护 只需要最少的系 统开销 。
连 接的添加
连 接池是 为每 个唯一的 连 接字符串 创 建的。当 创 建一个池后,将 创 建多个 连 接 对 象并将其添加到 该 池中,以 满 足最小池大小的要求。 连 接将根据需要添加到池中,直至达到最大池大小。
当 请 求 SqlConnection 对 象 时 ,如果存在可用的 连 接, 则 将从池中 获 取 该对 象。若要成 为 可用 连 接, 该连 接当前必 须 未被使用,具有匹配的事 务 上下文或者不与任何事 务 上下文相 关联 ,并 且具有与服 务 器的有效 链 接。
如果已达到最大池大小且不存在可用的 连 接, 则该请 求将会排 队 。当 连 接被 释 放回池中 时 , 连 接池管理程序通 过 重新分配 连 接来 满 足 这 些 请 求。 对 Connection 调 用 Close 或 Dispose 时 , 连 接被 释 放回池中。
警告 建 议 使用完 Connection 后始 终 将其 关闭 ,以便 连 接可以返回到池中。 这 可以使用 Connection 对 象的 Close 或 Dispose 方法来 实现 。不是 显 式 关闭 的 连 接可能不会添加或返回到池中。例如,如果 连 接已超出范 围 但没有 显 式 关闭 , 则仅 当达到最大池大小 而 该连 接仍然有效 时 , 该连 接才会返回到 连 接池中。
注意 不要在 类 的 Finalize 方法中 对 Connection 、 DataReader 或任何其他托管 对 象 调 用 Close 或 Dispose 。在 终结 器中, 仅释 放 类 直接 拥 有的非托管 资 源。 如果 类 不 拥 有任何非托管 资 源, 则 不要在 类 定 义 中包含 Finalize 方法。有 关 更多信息, 请 参 见 垃圾回收 编 程。
连 接的移除
如果 连 接生存期已 过 期,或者 连 接池管理程序 检测 到与服 务 器的 连 接已断 开 , 连 接池管理程序将从池中移除 该连 接。 请 注意,只有在 尝试 与服 务 器 进 行通信后,才可以 检测 到 这种 情况。如果 发现 某 连 接不再 连 接到服 务 器, 则 会将其 标记为 无效。 连 接池管理程序会定期 扫 描 连 接池, 查 找已 释 放到池中并 标记为 无效的 对 象。 找到后, 这 些 连 接将被永久移除。
// 连 接池 A 创 建了
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs";
conn.Open();
// 连 接池 B 创 建了,因 为 ConnectionString 与 A 不匹配
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// 使用 A 的 连 接池,因 为 ConnectionString 与 A 匹配
连 接池一旦 创 建,直到活 动进 程 终 止 时 才会被 毁 坏。 非活 动 或空池的 维护 只需要最少的系 统开销 。
连 接的添加
连 接池是 为每 个唯一的 连 接字符串 创 建的。当 创 建一个池后,将 创 建多个 连 接 对 象并将其添加到 该 池中,以 满 足最小池大小的要求。 连 接将根据需要添加到池中,直至达到最大池大小。
当 请 求 SqlConnection 对 象 时 ,如果存在可用的 连 接, 则 将从池中 获 取 该对 象。若要成 为 可用 连 接, 该连 接当前必 须 未被使用,具有匹配的事 务 上下文或者不与任何事 务 上下文相 关联 ,并 且具有与服 务 器的有效 链 接。
如果已达到最大池大小且不存在可用的 连 接, 则该请 求将会排 队 。当 连 接被 释 放回池中 时 , 连 接池管理程序通 过 重新分配 连 接来 满 足 这 些 请 求。 对 Connection 调 用 Close 或 Dispose 时 , 连 接被 释 放回池中。
警告 建 议 使用完 Connection 后始 终 将其 关闭 ,以便 连 接可以返回到池中。 这 可以使用 Connection 对 象的 Close 或 Dispose 方法来 实现 。不是 显 式 关闭 的 连 接可能不会添加或返回到池中。例如,如果 连 接已超出范 围 但没有 显 式 关闭 , 则仅 当达到最大池大小 而 该连 接仍然有效 时 , 该连 接才会返回到 连 接池中。
注意 不要在 类 的 Finalize 方法中 对 Connection 、 DataReader 或任何其他托管 对 象 调 用 Close 或 Dispose 。在 终结 器中, 仅释 放 类 直接 拥 有的非托管 资 源。 如果 类 不 拥 有任何非托管 资 源, 则 不要在 类 定 义 中包含 Finalize 方法。有 关 更多信息, 请 参 见 垃圾回收 编 程。
连 接的移除
如果 连 接生存期已 过 期,或者 连 接池管理程序 检测 到与服 务 器的 连 接已断 开 , 连 接池管理程序将从池中移除 该连 接。 请 注意,只有在 尝试 与服 务 器 进 行通信后,才可以 检测 到 这种 情况。如果 发现 某 连 接不再 连 接到服 务 器, 则 会将其 标记为 无效。 连 接池管理程序会定期 扫 描 连 接池, 查 找已 释 放到池中并 标记为 无效的 对 象。 找到后, 这 些 连 接将被永久移除。
如果存在与已消失的服
务
器的
连
接,那
么
即使
连
接池管理程序未
检测
到已断
开
的
连
接并将其
标记为
无效,仍有可能将此
连
接从池中取出。当
发
生
这种
情况
时
,将生成异常。但是,
为
了将
该连
接
释
放回池中,仍必
须
将其
关闭
。
字符串 关键 字:
Connection Lifetime 0 当 连 接返回到池中 时 ,将 对 它的 创 建 时间 和当前 时间进 行比 较 ,如果 时间间 隔超 过 由 Connection Lifetime 指定的 值 (以秒 为单 位), 则 会 毁 坏 该连 接。 在聚集配置中可以使用它来 强 制在运行服 务 器和 刚联 机的服 务 器之 间 达到 负载 平衡。
如果 值为 零 (0) , 则 将使池 连 接具有最大的超 时 期限。
Connection Reset 'true' 确定在从池中移除数据 库连 接 时 是否将其重置。 对 于 Microsoft SQL Server 版本 7.0 ,如果 设 置 为 false ,将避免在 获 取 连 接 时经历 一个 额 外的往返 过 程,但必 须 注意的是 连 接状 态 (如数据 库 上下文)不会被重置。
Enlist 'true' 当 为 true 时 ,如果存在事 务 上下文,池管理程序将自 动 在 创 建 线 程的当前事 务 上下文中登 记连 接。
Max Pool Size 100 池中允 许 的最大 连 接数。
Min Pool Size 0 池中 维护 的最小 连 接数。
Pooling 'true' 当 为 true 时 ,将从相 应 的池中取出 连 接,或者在必要 时创 建 连 接并将其添加到相 应 的池中。
实 例代 码 :
namespace HowTo.Samples.ADONET
{
using System;
using System.Data.SqlClient;
public class connectionpooling
{
public static void Main()
{
connectionpooling myconnectionpooling = new connectionpooling();
myconnectionpooling.Run();
}
字符串 关键 字:
Connection Lifetime 0 当 连 接返回到池中 时 ,将 对 它的 创 建 时间 和当前 时间进 行比 较 ,如果 时间间 隔超 过 由 Connection Lifetime 指定的 值 (以秒 为单 位), 则 会 毁 坏 该连 接。 在聚集配置中可以使用它来 强 制在运行服 务 器和 刚联 机的服 务 器之 间 达到 负载 平衡。
如果 值为 零 (0) , 则 将使池 连 接具有最大的超 时 期限。
Connection Reset 'true' 确定在从池中移除数据 库连 接 时 是否将其重置。 对 于 Microsoft SQL Server 版本 7.0 ,如果 设 置 为 false ,将避免在 获 取 连 接 时经历 一个 额 外的往返 过 程,但必 须 注意的是 连 接状 态 (如数据 库 上下文)不会被重置。
Enlist 'true' 当 为 true 时 ,如果存在事 务 上下文,池管理程序将自 动 在 创 建 线 程的当前事 务 上下文中登 记连 接。
Max Pool Size 100 池中允 许 的最大 连 接数。
Min Pool Size 0 池中 维护 的最小 连 接数。
Pooling 'true' 当 为 true 时 ,将从相 应 的池中取出 连 接,或者在必要 时创 建 连 接并将其添加到相 应 的池中。
实 例代 码 :
namespace HowTo.Samples.ADONET
{
using System;
using System.Data.SqlClient;
public class connectionpooling
{
public static void Main()
{
connectionpooling myconnectionpooling = new connectionpooling();
myconnectionpooling.Run();
}
public void Run()
{
try
{
String connString;
// Specification in the connection string:
// Please note: Pooling is implicit, you automatically get it unless you disable it.
// Therefore, "true" is the default for the pooling keyword (pooling=true).
// Connection Reset: False
// Connection Lifetime: 5
// Enlist: true
// Min Pool Size: 1
// Max Pool Size: 50
connString = "server=(local)//NetSDK;Trusted_Connection=yes;database=northwind;" +
"connection reset=false;" +
"connection lifetime=5;" +
"min pool size=1;" +
"max pool size=50";
SqlConnection myConnection1 = new SqlConnection(connString);
SqlConnection myConnection2 = new SqlConnection(connString);
SqlConnection myConnection3 = new SqlConnection(connString);
// Open two connections.
Console.WriteLine (" 打 开 两个 连 接。 ");
myConnection1.Open();
myConnection2.Open();
// Now there are two connections in the pool that matches the connection string.
// Return the both connections to the pool.
Console.WriteLine (" 将两个 连 接都返回到池中。 ");
myConnection1.Close();
{
try
{
String connString;
// Specification in the connection string:
// Please note: Pooling is implicit, you automatically get it unless you disable it.
// Therefore, "true" is the default for the pooling keyword (pooling=true).
// Connection Reset: False
// Connection Lifetime: 5
// Enlist: true
// Min Pool Size: 1
// Max Pool Size: 50
connString = "server=(local)//NetSDK;Trusted_Connection=yes;database=northwind;" +
"connection reset=false;" +
"connection lifetime=5;" +
"min pool size=1;" +
"max pool size=50";
SqlConnection myConnection1 = new SqlConnection(connString);
SqlConnection myConnection2 = new SqlConnection(connString);
SqlConnection myConnection3 = new SqlConnection(connString);
// Open two connections.
Console.WriteLine (" 打 开 两个 连 接。 ");
myConnection1.Open();
myConnection2.Open();
// Now there are two connections in the pool that matches the connection string.
// Return the both connections to the pool.
Console.WriteLine (" 将两个 连 接都返回到池中。 ");
myConnection1.Close();
myConnection2.Close();
// Get a connection out of the pool.
Console.WriteLine (" 从池中打 开 一个 连 接。 ");
myConnection1.Open();
// Get a second connection out of the pool.
Console.WriteLine (" 从池中打 开 第二个 连 接。 ");
myConnection2.Open();
// Open a third connection.
Console.WriteLine (" 打 开 第三个 连 接。 ");
myConnection3.Open();
// Return the all connections to the pool.
Console.WriteLine (" 将所有三个 连 接都返回到池中。 ");
myConnection1.Close();
myConnection2.Close();
myConnection3.Close();
}
catch (Exception e)
{
// Display the error.
Console.WriteLine(e.ToString());
}
}
// Get a connection out of the pool.
Console.WriteLine (" 从池中打 开 一个 连 接。 ");
myConnection1.Open();
// Get a second connection out of the pool.
Console.WriteLine (" 从池中打 开 第二个 连 接。 ");
myConnection2.Open();
// Open a third connection.
Console.WriteLine (" 打 开 第三个 连 接。 ");
myConnection3.Open();
// Return the all connections to the pool.
Console.WriteLine (" 将所有三个 连 接都返回到池中。 ");
myConnection1.Close();
myConnection2.Close();
myConnection3.Close();
}
catch (Exception e)
{
// Display the error.
Console.WriteLine(e.ToString());
}
}
}
}