【C#】事務(進程 ID 64)與另一個進程被死鎖在鎖資源上,并且已被選作死鎖犧牲品。請重新運行該事務。不能在具有唯一索引“XXX_Index”的對象“dbo.Test”中插入重復鍵的行。

🌹歡迎來到《小5講堂》🌹
🌹這是《C#》系列文章,每篇文章將以博主理解的角度展開講解。🌹
🌹溫馨提示:博主能力有限,理解水平有限,若有不對之處望指正!🌹

在這里插入圖片描述

目錄

  • 前言
  • 鎖定分析
    • Lock鎖對象
    • 事務鎖
    • 重復鍵
  • DeepSeek解決方案
    • 死鎖的原因
    • 解決方案
      • 1. **減少事務范圍**
      • 2. **優化 SQL 語句**
      • 3. **使用鎖提示**
      • 4. **重試機制**
      • 5. **檢查索引**
      • 6. **分析死鎖圖**
    • 示例代碼改進
    • 總結
  • 相關文章

前言

最近博主在開發一個項目時,用到的都是基本框架功能,有些造輪子的意思。
如果不留意,那么很容易犯一些代碼邏輯上的錯誤。
自己封裝框架和使用現有成熟框架最大區別就是容易踩坑,除非你有比較多的框架開發經驗。

鎖定分析

Lock鎖對象

這里博主犯了個小細節錯誤,鎖的對象和范圍邏輯不對,導致重復數據出現,大事務里存在同表查詢和添加,即使在小量并發下,出現爭搶資源,導致鎖。

實例化鎖對象
下面是錯誤寫法,有發現那里不對嗎?

namespace MvcMyNameSpace
{public class GetClass{private object lockObj = new object();public string GetNo(string tableName, string prefix){lock (lockObj){// 查詢表string sql = "select top 1 * from Test"}}}

靜態實例化
正確寫法,確保鎖對象是當前唯一

namespace MvcMyNameSpace
{public class GetClass{private static object lockObj = new object();public string GetNo(string tableName, string prefix){lock (lockObj){// 查詢表string sql = "select top 1 * from Test"}}}

鎖范圍
博主在上面獨立方法代碼塊加上鎖后,運行一段時間任務后,發現還是會出現重復索引。
后來排查發現,是并發會在最外層接口方法沒有鎖定。
之后在接口API整個方法加了鎖后,就再也沒有出現了重復索引。

事務鎖

博主這里是在一個大事務內進行了表查詢,在高并發下就會出現,多個事務可能同時嘗試更新或讀取相同的數據行或表,導致資源競爭。

重復鍵

對于sql server數據庫而言,可對表的字段設置唯一索引,確保數據庫表唯一性。
如果表設置了唯一索引,那么還會出現重復,說明程序端代碼邏輯不對,寫法有問題。
博主此處出現的錯誤就是在并發情況,至少有兩個并發同一時間獲取到同一條記錄。

DeepSeek解決方案

從你提供的代碼和錯誤信息來看,程序在執行 SQL 命令時遇到了死鎖問題。死鎖通常發生在多個事務同時競爭相同的資源,并且每個事務都在等待其他事務釋放鎖時發生。SQL Server 檢測到死鎖后,會選擇其中一個事務作為“犧牲品”并終止它,以便其他事務可以繼續執行。

死鎖的原因

在你的代碼中,死鎖可能由以下原因引起:

  1. 并發事務競爭相同的資源:多個事務可能同時嘗試更新或讀取相同的數據行或表,導致資源競爭。
  2. 事務范圍過大:如果事務涉及多個表或大量數據,死鎖的風險會增加。
  3. 鎖的順序不一致:如果不同的事務以不同的順序鎖定資源,可能會導致死鎖。

解決方案

以下是幾種可能的解決方案:

1. 減少事務范圍

  • 盡量減少事務的持續時間,確保事務只包含必要的操作。
  • 如果可能,將事務拆分為多個較小的事務,減少鎖的持有時間。

2. 優化 SQL 語句

  • 確保 SQL 語句盡可能高效,減少鎖的持有時間。
  • 使用 WITH (NOLOCK) 提示來避免讀取操作時的鎖競爭(但要注意臟讀的風險)。
  • 確保更新操作只鎖定必要的行,而不是整個表。

3. 使用鎖提示

  • 在 SQL 語句中使用鎖提示來控制鎖的行為。例如,使用 UPDLOCKROWLOCK 來減少鎖的粒度。
  • 例如:
    SELECT * FROM TableName WITH (UPDLOCK) WHERE ...
    

4. 重試機制

  • 在捕獲到死鎖異常后,實現重試機制。死鎖通常是暫時的,重試后事務可能會成功執行。
  • 例如:
    int retryCount = 3;
    while (retryCount > 0)
    {try{// 執行 SQL 命令cmd.ExecuteNonQuery();break;}catch (SqlException ex){if (ex.Number == 1205) // 1205 是死鎖錯誤代碼{retryCount--;if (retryCount == 0)throw; // 重試次數用盡,拋出異常Thread.Sleep(1000); // 等待一段時間后重試}else{throw; // 其他異常直接拋出}}
    }
    

5. 檢查索引

  • 確保表上有適當的索引,以減少鎖的競爭。缺少索引可能導致全表掃描,增加鎖的沖突。

6. 分析死鎖圖

  • 使用 SQL Server 的死鎖圖(Deadlock Graph)來分析死鎖的原因。你可以通過 SQL Server Profiler 或 Extended Events 來捕獲死鎖圖,了解哪些資源和事務導致了死鎖。

示例代碼改進

以下是一個簡單的重試機制示例,你可以在代碼中添加:

int retryCount = 3;
while (retryCount > 0)
{try{using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();using (SqlCommand cmd = new SqlCommand()){cmd.Connection = connection;foreach (String str in List){sqlText = "";// 添加參數ArrayList paramsArray = listParams[i];foreach (Dictionary<string, object> paramsItem in paramsArray){foreach (var keyItem in paramsItem){if (string.IsNullOrEmpty($"{keyItem.Value}")){cmd.Parameters.AddWithValue(keyItem.Key, DBNull.Value);}else{cmd.Parameters.AddWithValue(keyItem.Key, $"{keyItem.Value}");}if (str.Contains("update")){sqlText += $"{keyItem.Key.Replace("@", "")}='{keyItem.Value}',";}else{sqlText += $"'{keyItem.Value}',";}}}allSql = $"{str}";// 在這里執行你的 SQL 命令cmd.CommandText = str;cmd.ExecuteNonQuery();cmd.Parameters.Clear();i++;}rows += 1;}}break; // 執行成功,退出循環}catch (SqlException ex){if (ex.Number == 1205) // 1205 是死鎖錯誤代碼{retryCount--;if (retryCount == 0)throw; // 重試次數用盡,拋出異常Thread.Sleep(1000); // 等待一段時間后重試}else{throw; // 其他異常直接拋出}}
}

總結

死鎖是數據庫系統中常見的問題,通常通過優化事務范圍、SQL 語句、鎖策略以及實現重試機制來解決。通過分析死鎖圖和調整代碼邏輯,可以有效減少死鎖的發生。

相關文章

【C#】事務(進程 ID 64)與另一個進程被死鎖在鎖資源上,并且已被選作死鎖犧牲品。請重新運行該事務。不能在具有唯一索引“XXX_Index”的對象“dbo.Test”中插入重復鍵的行。

【C#】使用DeepSeek幫助評估數據庫性能問題,C# 使用定時任務,每隔一分鐘移除一次表,再重新創建表,和往新創建的表追加5萬多條記錄

【C#】合理使用DeepSeek相關AI應用為我們提供強有力的開發工具,在.net core 6.0框架下使用JsonNode動態解析json字符串,如何正確使用單問號和雙問號做好空值處理

【C#】已經實體類和動態實體類的反射使用方法,兩分鐘回顧,碼上就懂

【C#】使用vue3的axios發起get和post請求.net framework部署的API顯示跨域

【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel讀取數據以及保存數據

【C#】pdf按頁分割文件,以及分頁合并,效果還不錯,你值得擁有

【C#】未能加載文件或程序集“CefSharp.Core.Runtime.dll”或它的某一個依賴項。找不到指定的模塊。

【C#】.net core 6.0 在program時間格式統一json格式化,并列舉program默認寫法和簡化寫法

【C#】.net core 6.0 ApiController,API控制器方法,API接口以實體類作為接收參數應該注意的點

【C#】 SortedDictionary,查找字典中是否存在給定的關鍵字

【C#】.net core 6.0 MVC返回JsonResult顯示API接口返回值不可被JSON反序列化

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件詳細說明

【C#】使用代碼實現龍年春晚撲克牌魔術(守歲共此時),代碼實現篇

【C#】使用代碼實現龍年春晚撲克牌魔術(守歲共此時),流程描述篇

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91230.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91230.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91230.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode Hot 100 搜索二維矩陣

給你一個滿足下述兩條屬性的 m x n 整數矩陣&#xff1a;每行中的整數從左到右按非嚴格遞增順序排列。每行的第一個整數大于前一行的最后一個整數。給你一個整數 target &#xff0c;如果 target 在矩陣中&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。示例…

python畢設高分案例:基于機器學習的抑郁癥數據分析與預測系統,flask框架,算法包括XGboost模型、梯度提升樹模型等

1 緒論 1.1 課題研究背景和意義 1.1.1 研究背景 在醫療行業不斷發展的當下&#xff0c;數據量呈現出爆炸式增長&#xff0c;醫學數據的復雜性和多樣性也達到了前所未有的程度。電子病歷系統記錄了患者豐富的診療信息&#xff0c;醫學影像技術如 CT、MRI 等生成海量的圖像數據…

STM32與ADS1256多通道數據采樣原理及控制程序

好的,使用 STM32 與 ADS1256 通信讀取多通道電壓是精密數據采集的常見方案。ADS1256 是一款高精度、24 位、8 通道(或差分 4 通道)的 ΔΣ ADC,非常適合需要高分辨率的應用(如傳感器信號、醫療儀器等)。 以下是對整個過程的詳細分析及基于 STM32 HAL 庫的程序示例: 核…

Spring Boot 3.5.x 使用 SpringDoc 2 / Swagger3

這篇文章資料來自于網絡&#xff0c;對部分知識整理&#xff0c;這里只是記錄一下&#xff0c;僅供參考 為什么要用 Swagger Swagger 的核心思想是通過定義和描述 API 的規范、結構和交互方式&#xff0c;以提高 API 的可讀性、可靠性和易用性&#xff0c;同時降低 API 開發的難…

@RefreshScope 核心原理深度解析:Spring Boot 的動態魔法

讓我們通過全新的原理圖解和代碼級分析&#xff0c;揭開RefreshScope實現配置熱更新的神秘面紗&#xff01;一、工作原理全景圖&#xff08;優化版&#xff09; #mermaid-svg-50lhLlOFeSRIWnLn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px…

萬字詳解——OSI七層模型:網絡通信的完整架構解析

OSI七層模型&#xff1a;網絡通信的完整架構解析OSI&#xff08;Open Systems Interconnection&#xff09;七層模型是計算機網絡領域最基礎、最權威的參考框架。它由國際標準化組織&#xff08;ISO&#xff09;于1984年提出&#xff0c;旨在為不同廠商、不同技術的網絡設備和系…

一個人開發一個App(OpenApi)

為了少寫代碼&#xff0c;統一前后端的網絡層&#xff0c;我使用了OpenApi設計restful接口。然后用openapi-generator來生成flutter的代碼。生成go代碼用的是oapi-codegen,它對go更友好一些。 我們直接在api.yml中設計接口&#xff0c;所有的返回值與請求者都提取到components里…

光伏氣象監測系統:助力光伏發電的智慧大腦

光伏氣象監測系統&#xff1a;助力光伏發電的智慧大腦 柏峰【BF-GFQX】在全球積極推動能源轉型、大力倡導 “雙碳” 目標的當下&#xff0c;光伏發電憑借其清潔、可再生的顯著優勢&#xff0c;宛如一顆冉冉升起的新星&#xff0c;在能源領域迅速嶄露頭角&#xff0c;得以廣泛推…

SpringCloud01——項目演變、微服務遠程調用三種方式、springcloud介紹、nacos注冊中心

目錄 一、項目架構演變過程 1、單體應用架構 2、垂直應用架構 3、分布式服務架構 4、流動計算架構&#xff08;SOA架構&#xff09; 5、微服務架構 二、如何實現微服務遠程調用 1、HttpClient工具類&#xff08;springboot中&#xff09; 形式1&#xff1a;調用第三方…

Oracle 和 MySQL 中的日期類型比較

Oracle 和 MySQL 都提供了多種日期和時間數據類型&#xff0c;但它們在實現和功能上有一些差異。以下是兩者的主要日期類型對比&#xff1a;Oracle 日期類型DATE存儲日期和時間&#xff08;精確到秒&#xff09;格式&#xff1a;YYYY-MM-DD HH24:MI:SS示例&#xff1a;TO_DATE(…

基于 Redis 實現共享 Session 登錄的多種方法與實踐

全文目錄&#xff1a;開篇語**前言****1. 什么是共享 Session 登錄&#xff1f;****2. 基于 Redis 實現共享 Session 的基本方法****2.1 通過 Redis 存儲 Session 數據****2.1.1 基本流程****2.1.2 示例代碼&#xff08;Java Spring Boot Redis&#xff09;****3. 使用 Redis…

spring cloud + easyRules 零基礎搭建智能規則引擎

你是否曾想過在項目中嵌入一套輕量級且高度可擴展的規則引擎&#xff0c;輕松實現動態化的業務決策&#xff1f;在金融、電商、政務等領域&#xff0c;風險控制是業務安全的核心。傳統硬編碼方式很難應對復雜多變的風控需求&#xff0c;而規則引擎允許我們將這些規則獨立出來&a…

AI應用:電路板設計

Diode Computers 公司 Diode Computers是一家專注于利用AI技術進行定制電路板設計和制造的公司&#xff0c;提供從概念到量產的全流程服務。其核心優勢在于將電路板設計轉化為AI可理解的代碼形式&#xff0c;大幅提升設計效率并降低傳統EDA工具的使用門檻 0。 核心服務 設計與制…

RocketMQ學習系列之——客戶端消息確認機制

一、客戶端使用MQ基本代碼示例1、添加maven依賴<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>5.3.0</version> </dependency>2、生產者代碼示例public class Produc…

[leetcode] 組合總和

39. 組合總和 - 力扣&#xff08;LeetCode&#xff09; i class Solution {int aim;vector<vector<int>> ret;vector<int> path; public:vector<vector<int>> combinationSum(vector<int>& nums, int target) {aim target;dfs(nums…

新能源行業B端極簡設計:碳中和目標下的交互輕量化實踐

新能源行業B端極簡設計&#xff1a;碳中和目標下的交互輕量化實踐內容摘要在新能源行業&#xff0c;碳中和目標正推動著企業追求更高的運營效率和更低的資源消耗。然而&#xff0c;傳統的B端交互設計往往復雜繁瑣&#xff0c;不僅增加了用戶的操作成本&#xff0c;還可能導致資…

減速機:自動化生產線的“精密傳動心臟”

減速機作為自動化生產線的核心傳動部件&#xff0c;通過調節轉速與扭矩實現設備精準控制&#xff0c;其在自動化生產線中發揮著關鍵作用。以下是其具體應用方式&#xff1a;輸送線驅動在自動化生產線中&#xff0c;輸送線用于運輸物料、半成品或成品&#xff0c;通過減速機可以…

從0到1學PHP(五):PHP 數組:高效存儲與處理數據

目錄一、數組的定義與分類1.1 索引數組1.2 關聯數組1.3 多維數組二、數組的基本操作2.1 數組元素的添加、刪除、修改和訪問2.2 數組指針的操作三、數組處理函數3.1 數組排序函數3.2 數組統計函數3.3 數組過濾與轉換函數一、數組的定義與分類 在 PHP 中&#xff0c;數組是一種非…

vscode 字體的跟換

打開vscode 左下角輸入電腦中已經有的字體&#xff1a;有想要用的可以自己進行安裝刷新這樣就可改變了

墨者:SQL過濾字符后手工注入漏洞測試(第3題)

1. 墨者學院&#xff1a;SQL過濾字符后手工注入漏洞測試(第3題)&#x1f680; 因為練習過太多的sql注入&#xff0c;廢話不多介紹&#xff0c;我會通過圍繞手動注入和工具爆破的方式達到靶場目標&#xff0c;開練&#xff01;&#xff01;&#xff01; 2. 手工注入方式&#x1…