如何在C#中保护SqlDataReader免受多重访问

时间:2012-05-01 08:22:30

标签: c# multithreading sqldatareader

我有一个用C#编写的多线程TCP服务器软件。许多线程应该从数据库读取,我使用SqlDataReader从数据库读取。当一个线程想要从数据库中读取时,没有问题但是当两个或更多线程想要从数据库中读取时,这种情况开始成为问题。 .NET给出了这个例外:已经有一个与此命令关联的打开DataReader,必须先关闭它。

如何防止错误?如何保护SqlDataReader免受多重访问?互斥是否适合这个问题?

3 个答案:

答案 0 :(得分:3)

  

如何保护SqlDataReader免受多重访问?

甚至不要共享连接。

为每个数据库操作创建一个新的SqlConnection(在using语句中,以便在操作结束时处置它),并让连接池处理使其有效。

如果您没有共享连接,则不会出现此错误,并且您不会通过锁定序列化数据库访问。

答案 1 :(得分:3)

您应该向.net运行时询问每个线程内的新sql连接。就速度而言,这是最佳解决方案(这使用.net的sql连接池,因此您不会浪费时间建立连接)。

答案 2 :(得分:2)

我建议为每个请求创建一个新连接 ,而不是尝试重新使用现有的活动连接。我假设您正在使用某种类成员或静态引用连接,而不是使用方法范围:

private void RespondingToTcpRequest()
{
    using (var connection = new SqlConnection(""))
    using (var command = new SqlCommand("", connection))
    {
         connection.Open();

         using (var reader = command.ExecuteReader())
         {
             // No locks or sharing issues here!
         }
    }
}

如果我有一些示例代码展示您目前拥有的内容,我可以根据您的情况调整该想法。

至于锁定,如果真的想要沿着这条路走下去(严肃地说,不要),你需要做的就是锁定(基本的一个)同步原语):

private static readonly object ReaderLock = new object();

private void RespondingToTcpRequest()
{
    lock (ReaderLock)
    {
        // database connection, command, reader stuff here.
    }
}

不一定需要互斥锁,因为问题将是进程本地的,其中lock关键字就足够了。再说一遍,不要