【问题标题】:Deadlocked on lock resources in sqlsql中锁资源死锁
【发布时间】:2018-12-23 18:44:52
【问题描述】:

我在windows应用程序中工作c#多线程功能(5线程)超过2M的数据,同时用我的内部代码删除突然发生死锁错误帮助如何纠正和解决问题 错误:事务(进程 ID 59)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务

我参考了网站并找到了一个查询来解决这个问题在这里我提到了那个查询但有时它在某些时候它不起作用 SQL: ALTER DATABASE DBName SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE 去

帮助如何解决这个问题,无论是在代码还是 sql 管理中我应该改变什么

代码

if (SqlCon.State == ConnectionState.Closed)
{
   OpenConnection();
}

string sqlStmt = "Delete em from Order em inner join OrderHeader ch on ch.CartonId=em.CartonId and ch.OrderNumber = " + "'" + OrderNumber + "'";
SqlCmd.CommandText = sqlStmt;

SqlCommand.CommandTimeout = TimeoutPeriod();
SqlTransaction transaction;

// Start a local transaction.
transaction = SqlCon.BeginTransaction(IsolationLevel.ReadCommitted);

// Must assign both transaction object and connection
// to Command object for a pending local transaction
SqlCommand.Connection = SqlCon;
SqlCommand.Transaction = transaction;

try
{

   int val = SqlCommand.ExecuteNonQuery();

   // Attempt to commit the transaction.
   transaction.Commit();
   return true;
}
catch (Exception ex)
{
   throw ex;
}
finally
{
   CloseConnection(SqlCon);
}

【问题讨论】:

  • 您知道什么是死锁以及为什么会发生死锁吗?解决问题的方法有很多,但都是定制的
  • 你可以参考这篇文章:- DeadLock
  • @BossRoss 线程同时处理所有线程都请求特定表然后发生死锁对吗?
  • 这是一个很难解决的问题,你需要先弄清楚事务锁定了哪些查询,然后才能弄清楚你能做些什么
  • @TheGeneral 删除基于订单号的订单,带where条件的简单删除查询!

标签: c# sql sql-server deadlock database-deadlocks


【解决方案1】:

READ_COMMITTED_SNAPSHOT 数据库选项将有助于避免与读取器和写入器而不是写入器和写入器之间的阻塞/死锁(并发 DELETE 语句)。

在下面运行此查询,从 system_health 跟踪中获取最近的死锁详细信息:

WITH
      CurrentSystemHealthTraceFile AS (
        SELECT CAST(target_data AS xml).value('(/EventFileTarget/File/@name)[1]', 'varchar(255)') AS FileName
        FROM sys.dm_xe_session_targets
        WHERE
            target_name = 'event_file'
            AND CAST(target_data AS xml).value('(/EventFileTarget/File/@name)[1]', 'varchar(255)') LIKE '%\system[_]health%'
    )
    , AllSystemHealthFiles AS (
        SELECT 
            REVERSE(SUBSTRING(REVERSE(FileName), CHARINDEX(N'\', REVERSE(FileName)), 255)) + N'system_health*.xel' AS FileNamePattern
        FROM CurrentSystemHealthTraceFile
        )
    , DeadLockReports AS (
        SELECT CAST(event_data AS xml) AS event_data
        FROM AllSystemHealthFiles
        CROSS APPLY sys.fn_xe_file_target_read_file ( FileNamePattern, NULL, NULL, NULL) AS xed
        WHERE xed.object_name like 'xml_deadlock_report'
    )
SELECT TOP 10
      DATEADD(hour, DATEDIFF(hour, SYSUTCDATETIME(), SYSDATETIME()), event_data.value('(/event/@timestamp)[1]', 'datetime2')) AS LocalTime
    , event_data AS DeadlockReport
FROM DeadLockReports;

通常可以通过查询和索引调整来避免死锁,以便只触及任务所需的那些行。在这种情况下,Order.CartonID 上的索引 OrderHeader(OrderID, CartonID) 上的复合(理想情况下是唯一的)索引看起来很有用。

另外,使用与列数据类型匹配的OrderID 参数类型参数化您的查询。

【讨论】:

  • READ_COMMITTED_SNAPSHOT 再次无法工作我面临死锁问题@Dan Guzam
  • @jose,我说过 READ_COMMITTED_SNAPSHOT 不会帮助防止并发 DELETE 语句的死锁。您是否在我的答案中运行了查询?您查看过索引吗?
  • yes 在我这边运行此查询并在 xml 中获取死锁报告
  • @jose,在您的问题中添加 XML 死锁报告。
  • 它太大了@Dan
猜你喜欢
  • 2013-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多