数据库连接

大多数数据库接口依赖于某些数据库连接对象,它们好像应用程序代码和数据库之间的桥梁。通常,一个连接必须在执行数据库操作命令之前就要打开。实际上,经常需要一个显示连接来建立和执行命令。在命令执行的整个过程中,该连接必须是打开的,查询的结果将返回一个记录集,才关闭数据库连接。如果正在一个事务中运行,经常会把事务绑定在特定的连接上,当它运行的时候这个连接也必须一直打开,直到这个事务结束才能关闭连接。
在很多环境中,建立连接的开销相当大,这就需要建立一个连接池。在这种情况下,开发者向连接池请求一个连接并在完成以后释放,而无需即时创建和关闭。注意这里不是要你自己去创建连接池,因为现在多数平台都会提供连接池,所以很少需要自己来实现连接池。如果必须自己实现连接池,首先就要检查连接池是不是真的能提高性能(对连接池的创建可以参考后面的代码【1】)。还要注意:越来越多的环境使我们可以更快地创建新的连接,因此也不需要使用缓冲池。
提供连接池的环境把连接池放在一个类似创建新连接的接口后面。用这种方法,无需知道得到得是一个新创建连接还是从连接池里面分配的。类似地,关闭一个连接可能并没有真正关闭它,而只是把它替换为从连接池获取和释放。
无论创建连接的代价是高还是低,连接都必须好好管理,因为它们是珍贵的资源,必须在使用完毕时立刻关闭。还有,如果正在进行一次事务,通常需要保证:在这次特定的事务中,每一个命令都是从同一个连接发出的。
最常见的建议就是用一个到连接池或者连接管理器的调用,显示得到一个连接,并且通过它来执行数据库命令,一旦执行完了,立刻把它关闭。这个建议带来两个问题:首先,保证在任何需要的地方都能得到一个连接;其次,保证不会在最后忘记关闭它(可以参考后面得示例代码【2】)。
现代环境提供了自动的内存管理和垃圾回收机制,因此保证连接关闭的一种方法就是使用垃圾回收器。在这种方式下,连接自身或者引用这个连接的对象会在垃圾回收期间关闭连接。这样做的好处是:它使用了和内存管理相同的机制,同样方便,也不陌生。这样做的问题是:连接的关闭只有当垃圾回收器实际回收内存的时候才发生,可能离这个连接失去它最后一次引用的时间已经很久了,结果是未被引用的连接可能会隔一段时间才被关闭。总的来说,我不喜欢依赖垃圾回收机制,对于其它的机制,甚至是显示关闭都会好一些。当然,垃圾回收机制在其它机制失败的情况下还是一种很好的后备。
连接管理细节描述的往往是数据库交互软件的特征,因此所使用的策略通常是由环境来决定的。
连接池的创建示例代码【1】:
using System;
using System.Timers;
using System.Collections;
using System.Data.SqlClient;
using Common;

namespace SqlDBConnection
... {
/**////<summary>
///DBConnection的数据库连接对象池。
///</summary>

publicsealedclassDBConnection:ObjectPool
...{
privateDBConnection()
...{
}


publicstaticreadonlyDBConnectionInstance=newDBConnection();

privatestaticstring_connectionstring="数据库连接字符串";

publicstaticstringConnectionstring
...{
set
...{
_connectionstring
=value;
}

get
...{
return_connectionstring;
}

}


protectedoverrideobjectCreate()
...{
try
...{
SqlConnectiontemp
=newSqlConnection(_connectionstring);
temp.Open();
return(temp);
}

catch
...{
returnnull;
}

}


protectedoverrideboolValidate(objecto)
...{
try
...{
SqlConnectiontemp
=(SqlConnection)o;
return(!((temp.State.Equals(System.Data.ConnectionState.Closed))));
}

catch(SqlException)
...{
returnfalse;
}

}


protectedoverridevoidExpire(objecto)
...{
try
...{
((SqlConnection)o).Close();
}

catch(SqlException)
...{
}

}


publicSqlConnectionBorrowDBConnection()
...{
try
...{
return((SqlConnection)base.GetObjectFromPool());
}

catch(Exceptione)
...{
throwe;
}

}


publicvoidReturnDBConnection(SqlConnectionc)
...{
base.ReturnObjectToPool(c);
}

}


/**////<summary>
///ObjectPool的对象池。
///</summary>

publicabstractclassObjectPool
...{
privatelong_lastCheckOut;
privatestaticHashtablelocked;
privatestaticHashtableunlocked;
internalstaticlongCARBAGE_INTERVAL=9*1000;

staticObjectPool()
...{
locked
=Hashtable.Synchronized(newHashtable());
unlocked
=Hashtable.Synchronized(newHashtable());
}


internalObjectPool()
...{
_lastCheckOut
=DateTime.Now.Ticks;
System.Timers.TimeraTimer
=newSystem.Timers.Timer();
aTimer.Enabled
=true;
aTimer.Interval
=CARBAGE_INTERVAL;
aTimer.Elapsed
+=newSystem.Timers.ElapsedEventHandler(CollectGarbage);
}


protectedabstractobjectCreate();

protectedabstractboolValidate(objecto);

protectedabstractvoidExpire(objecto);

internalobjectGetObjectFromPool()
...{
longnow=DateTime.Now.Ticks;
_lastCheckOut
=now;
objecto=null;
o
=Create();
locked.Add(o,now);
return(o);
}


internalvoidReturnObjectToPool(objecto)
...{
if(o!=null)
...{
lock(this)
...{
locked.Remove(o);
unlocked.Add(o,DateTime.Now.Ticks);
}

}

}


privatevoidCollectGarbage(objectsender,System.Timers.ElapsedEventArgsea)
...{
lock(this)
...{
objecto;
longnow=DateTime.Now.Ticks;
IDictionaryEnumeratore
=unlocked.GetEnumerator();

try
...{
while(e.MoveNext())
...{
o
=e.Key;
if((now-((long)unlocked[o]))>CARBAGE_INTERVAL)
...{
unlocked.Remove(o);
Expire(o);
o
=null;
}

}

}

catch(Exception)...{}
}

}

}

}
数据库连接示例代码【2】:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using SqlDBConnection;
using Common;

namespace MyMedia_Competitor
... {
/**////<summary>
///SqlDataBase的摘要说明。
///</summary>

publicclassMySqlDataBase
...{
/**////<summary>
///构造函数
///</summary>

publicMySqlDataBase()
...{
}

publicDBConnectionConnection;

/**////<summary>
///获取数据库连接接口
///</summary>

publicIDbConnectionGetConnection()
...{
IDbConnectionsqlConnection1
=null;
stringconnectionstring="数据库连接字符串";
sqlConnection1
=(IDbConnection)newSqlConnection(connectionstring);
sqlConnection1.Open();
returnsqlConnection1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值