Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 锁定会导致数据库操作太慢_C#_Multithreading_Locking_Msdtc - Fatal编程技术网

C# 锁定会导致数据库操作太慢

C# 锁定会导致数据库操作太慢,c#,multithreading,locking,msdtc,C#,Multithreading,Locking,Msdtc,我遇到了一个问题,多线程处理可能会导致空连接出现问题,因为它们可以被同时运行的多个线程打开和关闭。我试图通过锁定上面的过程来解决这个问题,为了清晰起见,代码进行了简化,但发现这会严重降低性能 我尝试使用两个单独的锁来创建/处理数据库连接,并在锁定之外执行数据库操作,从而绕过此问题: lock (_connectionLock) { if (conn == null) { conn = GetOpenConnection(connectionString); }

我遇到了一个问题,多线程处理可能会导致空连接出现问题,因为它们可以被同时运行的多个线程打开和关闭。我试图通过锁定上面的过程来解决这个问题,为了清晰起见,代码进行了简化,但发现这会严重降低性能

我尝试使用两个单独的锁来创建/处理数据库连接,并在锁定之外执行数据库操作,从而绕过此问题:

lock (_connectionLock) {
    if (conn == null) {
        conn = GetOpenConnection(connectionString);
    } 

    try {
        PerformDbAction(conn);
    } finally {
        conn.Dispose();
    }
}
只有我意识到上述方法不起作用,因为另一个线程可能会尝试使用已由另一个线程处理的连接执行数据库操作

有谁能推荐一种替代方案或解决方案,在这种方案中,我可以安全地锁定对数据库连接字符串的访问,而不会让一切都慢下来这么多

编辑:很抱歉之前没有包括这一点,但我不只是创建新连接并立即处理它们的原因是我试图避免不必要的MSDTC升级。在使用GetOpenConnection时,我正在重用现有连接,因为这是触发MSDTC升级的因素之一

我已经设法避免了顶部代码示例的升级,但它的执行速度太慢了

只是没有一个共享连接变量。相反,每次你需要做某事时,打开一个连接,使用它,然后尽快关闭它。您不需要在代码中使用任何锁,连接池将管理到数据库的实际网络连接

目前,您基本上构建了一个只包含一个连接的基本连接池,这意味着您在数据库中根本没有并发性,而不是每个进程。

只是没有一个共享连接变量。相反,每次你需要做某事时,打开一个连接,使用它,然后尽快关闭它。您不需要在代码中使用任何锁,连接池将管理到数据库的实际网络连接



目前,您实际上已经构建了一个只包含一个连接的基本连接池,这意味着您在数据库中根本没有并发性,而不是每个进程。

您只使用一个连接吗?同时使用多个锁,每个线程一个,既安全又好,不过如果处理相同的数据,最终数据库引擎将为您处理锁。等等,什么?如何以空连接字符串结束?你是说空连接吗?那是另一回事。你能发布GetOpenConnection方法的代码吗?@Tyler:别这么做。每次创建一个新连接,并让数据库提供程序自己进行池处理。不要跨线程共享任何内容。@SLaks将尝试一下。谢谢卡博特的代码格式,当我把它粘贴进去的时候,它就到处都是。您是如何做到的?选择代码并按Control-K。您是否仅使用1个连接?同时使用多个锁,每个线程一个,既安全又好,不过如果处理相同的数据,最终数据库引擎将为您处理锁。等等,什么?如何以空连接字符串结束?你是说空连接吗?那是另一回事。你能发布GetOpenConnection方法的代码吗?@Tyler:别这么做。每次创建一个新连接,并让数据库提供程序自己进行池处理。不要跨线程共享任何内容。@SLaks将尝试一下。谢谢卡博特的代码格式,当我把它粘贴进去的时候,它就到处都是。您是如何做到的?选择代码并按Control-K。我这样做是为了尝试避免多个连接或来自多个Linq数据上下文的同一连接出现MSDTC问题,至少是这样。谢谢你的回答,我会给你一个答案try@Tyler当前位置你应该给出这些问题的详细信息-这几乎肯定不是解决这些问题的正确方法。很抱歉没有在问题中包括这些。你对我如何处理这个问题以及如何避免MSDTC升级有什么建议吗?@Tyler:使用连接池,你最终应该在可以的情况下重用同一个连接。我这样做是为了避免多个连接或来自多个Linq数据的同一个连接出现MSDTC问题至少是上下文。谢谢你的回答,我会给你一个答案try@Tyler当前位置你应该给出这些问题的详细信息-这几乎肯定不是解决这些问题的正确方法。很抱歉没有在问题中包括这些。你对我如何处理这个问题以及如何避免MSDTC升级有什么建议吗?@Tyler:使用连接池,你应该在可以的地方重新使用相同的连接。
lock (_connectionLock) {
    if (conn == null) {
        conn = GetOpenConnection(connectionString);
    } 
}

try {
    PerformDbAction(conn);
} finally {
    lock(_connectionLock) 
    conn.Dispose();
}
}