我有一个使用.NET Remoting的客户端服务器应用程序 我的app DBQuery的服务器部分有一个帮助类 DBQuery包含DatabaseConnection和SQLCommand对象Commander,并执行传递给它的查询。
每次执行查询时,都会验证Commander是否已打开连接 (如有必要,它会重新创建指挥官。)
考虑到它只连接到一个数据库,我应该让我的DBConnection静态吗?
(DBConnection创建命令器DBConnection.CreateCommand()
)
下面定义的当前属性:
/// <summary> connection used for querying with </summary>
public DBConn DBConnection
{ get { return _conn ?? (_conn = new DBConn()); } }
/// <summary> Command object for processing the queries </summary>
private SqlCommand Commander
{
get
{
return _commander ??
(_commander = DBConnection.Connection.CreateCommand());
}
}
DBConn
- 包装SqlConnection
并从app.config提供相应的连接信息
答案 0 :(得分:1)
即使它是静态的, 从不 使用单个连接 - 有一件事我不相信连接是线程安全的,所以它不一定需要善意地从两个不同的客户那里并行调用。
即使我错了(如果我错了,我仍然不会在多个线程之间共享一个连接),但是如果数据库服务器发生了某些事情,让我们说它重新启动或者服务本身就是这样(由于您的支持团队发布了升级),连接将被删除,您无法再次重新打开 - 您的服务/应用程序必须重新启动。实际上,当你下次尝试使用它时,它实际上最终会抛出异常。
另外,你在哪里处理连接?处理静态对象非常困难,除非你做了挂钩事件的工作,这并不总是可靠的。依靠AppDomain的关闭为你处理的事情并不是一种好的做法。
在您需要时创建连接,并在完成后将其丢弃。基于您给出的代码,用最简单的术语表示:
using(var conn = new DbConn().Connection)
{
SqlCommand command = conn.CreateCommand();
/* query and get results here */
}
虽然实际上您可能想要DbConn
类IDisposable
并在Connection
的{{1}}实现中链接到基础Dispose
的{{1}}方法 - 你可以这样做
IDisposable.Dispose
注意 - 如果用工厂方法或属性get替换using(var dbconn = new DbConn())
{
//now you can use dbconn.Connection knowing that it will be disposed of
}
,using
块仍然有效 - 它只是确保在块退出时在对象上调用new DbConn()
,即使发生异常。
通过这样做,你可以解决我在答案的前半部分突出显示的所有问题。
答案 1 :(得分:0)
基础架构正在幕后进行连接管理(包括池化),因此我的建议是保持代码清洁,不要让它成为静态代码。