Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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# 多线程程序中的Sql server锁异常_C#_Sql Server_Multithreading_Stored Procedures - Fatal编程技术网

C# 多线程程序中的Sql server锁异常

C# 多线程程序中的Sql server锁异常,c#,sql-server,multithreading,stored-procedures,C#,Sql Server,Multithreading,Stored Procedures,在一个c#程序中,我有两个线程来启动一个存储过程。 此存储过程读取和写入某些表中的数据 启动程序时,有时会出现SQL server异常(锁故障) 为了避免死锁,我尝试在程序中添加一个锁(this){…},以避免同时调用这个存储过程,但没有成功(相同的异常) 如何解决这个问题?锁(this)不会解决并发问题,如果类的多个实例正在运行,因为锁将引用不同的this引用,即 public class Locker { public void Work() { lock (this

在一个c#程序中,我有两个线程来启动一个存储过程。 此存储过程读取和写入某些表中的数据

启动程序时,有时会出现SQL server异常(锁故障)

为了避免死锁,我尝试在程序中添加一个
锁(this){…}
,以避免同时调用这个存储过程,但没有成功(相同的异常)

如何解决这个问题?

锁(this)
不会解决并发问题,如果类的多个实例正在运行,因为锁将引用不同的
this
引用,即

public class Locker
{
   public void Work()
   {
      lock (this)
      {
         //do something
      }
   }
}
用作(假设这些代码并行运行)

将在两种情况下锁定同一个对象,并使第二个呼叫等待


但是,根据我的经验,在大多数情况下,SQL Server过程中的锁问题都是过程本身的错误,使事务打开的时间超过必要的时间,打开不需要的事务,查询不理想等。使sp调用在C#代码中排队等待,而不是在SQL Server排队等待,并不能解决这些问题

此外,死锁是一类特定的并发性问题,几乎总是可以通过在考虑数据访问的情况下重构解决方案来解决。请向我们提供有关该问题的更多信息,可能有一种解决方案根本不需要应用程序级锁。

正如@SWeko所解释的,C#的
锁将只解决当前AppDomain线程之间的并发问题,因此,如果有多个AppDomain正在运行,为了简单起见,让我们假设两个桌面客户端,然后他们就会陷入僵局。有关更多详细信息,请参阅和


即使是在桌面应用程序中,最好在存储过程中处理死锁问题。默认行为是,您的第二个请求将等待第一个请求完成,直到超时,如果您不想等待,则使用
WITH(NOWAIT)

如果您可以在SP中显示代码,那么就可以更容易地找出出现死锁的原因。您是对的,但我不会在应用程序代码中使用锁来防止数据库死锁,因为它是一种过于生硬的工具。SP可能需要进行调整。@ShellShock我同意,并对此进行了澄清,但同样重要的是不要错误地使用
lock
语句,因为这样会产生“看起来正确”的代码。
Locker first = new Locker();                Locker second = new Locker();
first.Work() // <-- locks on first          second.Work() // <-- locks on second
public class Locker
{
   private static object lockObject = new object(); 
   // a static doodad for locking

   public void Work()
   {
      lock (lockObject)
      {
         //do something
      }
   }
}