【问题标题】:working with database Best practise?使用数据库 最佳实践?
【发布时间】:2010-11-06 14:40:55
【问题描述】:

我有一个 C# 数据库层,它具有在后台计时器中每秒调用一次的静态读取方法。

目前我创建 SqlCommand、SqlConnection 一次作为类成员。

在每个方法调用中我都执行命令来获取结果,我这样做是为了避免每秒创建连接和命令,但我担心这个方法会发生异常,会中断连接或将对象放入无效状态。

这是我当前的实现(定时器处理程序)

    static void GetBarTime(object state)
    {
        lock (_staticConnection)
        {
            SqlDataReader dataReader = null;
            try
            {
                dataReader = _getMaxTimeCommand.ExecuteReader();
                dataReader.Read();
                _currentTick = dataReader.GetInt32(0);
            }
            catch (Exception ex)
            {
                //Log the error
            }
            finally
            {
                dataReader.Dispose();
            }
        }
    }

最好的做法是什么?

更多详情:

我在计时器中执行此操作,因为有另一个进程每秒更新我的表,并且一组客户端使用另一个公开的方法并每秒调用一次以获取最新值。

因此,我不是每秒为每个客户端执行 select 语句,而是在计时器中执行此操作并更新客户端使用的全局变量。

【问题讨论】:

  • 你能解释一下这个场景,为什么你需要在计时器中编写代码来从数据库中读取东西吗? DB 值的变化频率如何?

标签: c# database ado.net


【解决方案1】:

SqlConnection 内置了池化;如果你使用,你会发现几乎没有区别:

using(SqlConnection conn = new SqlConnection(connectionString)) {
    conn.Open();
    // your code
}

每次。这可以自动对死(底层)连接做出反应。

目前你有一个错误,顺便说一句;如果命令失败,阅读器仍将为空……在调用Dispose()之前检查null:

if(dataReader !=null) {dataReader.Dispose();}

或者直接使用using:

 try
 {
     using(SqlDataReader dataReader = _getMaxTimeCommand.ExecuteReader())
     {
         dataReader.Read();
         _currentTick = dataReader.GetInt32(0);
     }
 }
 catch (Exception ex)
 {
    //Log the error
 }

【讨论】:

  • 好,但从逻辑上来说,是更好还是为每个调用创建连接和命令?
  • 通常是的,每次通话更好;您对状态管理/线程/等没有任何问题。它还部分取决于命令的外观 - 例如,存储过程在保留准备好的命令方面没有任何真正的优势。
  • 我不是要求一般情况,对于我的情况,方法每秒调用一次,我知道有连接池,但是每次调用打开和关闭连接都会消耗一些时间,而不是为此有专用连接方法
  • 不,不是——底层连接保持打开状态。您只有时间从托管池中获取,这绝对是很小的,并且与执行进程外(可能还有网络-基于)IO 到服务器。
【解决方案2】:

很难确定一个执行是否意味着连接是一个死鸭子。为了安全起见,您可以在遇到异常时关闭并重新打开 SqlConnection 和 SqlCommand,以防万一。当一切正常时,这不会造成任何开销。

【讨论】:

  • 所以我可以使用相同的代码,但只是在异常处理中关闭并再次打开连接?
  • IMO 更好:在异常处理程序中,只需将其关闭并将其设置为 null。在 GetBarTime 中,在 lock() 块中,检查连接是否为空;如果是,打开它并创建 SqlStatement。通过这种方式,可以更轻松地避免数据库在一段时间不可用时出现的问题。
  • (续)因为如果出现异常,重新打开连接也可能会失败...
猜你喜欢
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
相关资源
最近更新 更多