我有以下場景..
- 員工記錄已創建
- NextPayrollNumber 從資料庫表(設定表)中的記錄中讀取
- Number 加 1 并作為 PayrollNumber 添加到 Employee 記錄,并覆寫當前 NextPayrollNumber
- 員工記錄保存到資料庫(員工表)
我需要確保兩個 Employee 記錄不會有相同的編號,并且我已經進行了一些搜索,看起來并發問題通常是使用并發令牌處理的,并在 DBContext 中進行并發例外處理。但這涉及向設定表添加另一列以存盤 rowversion,并向 dbcontext 添加僅用于這一要求而應用程式的其余部分不需要的代碼。
還有其他方法來處理這個嗎?我希望向資料庫表添加一個唯一約束(但該列將具有空值)或使用一個序列,但該值需要基于最終用戶可配置的 NextPayrollNumber。
uj5u.com熱心網友回復:
鑒于工資單 # 不是該行的 PK(使用內置標識),并且您不想從 PK 標識派生工資單編號,那么我的建議是安全而不是擔心 2 的例外情況插入一起發生,通過對 Payroll # 具有唯一約束的重試來處理例外。基本上填充工資單#并盡快保存記錄,如果您遇到重復的例外(應該很少見)通過從您的設定中獲取新的工資單#來處理它(確保您重新加載設定物體或從資料庫中獲取不快取的行)并再次保存,必要時重試。如果下一個 # 與您檢索到的相同,那么您的插入存在更大的問題,并且可以通過例外訊息保釋。
var settings = _context.Settings.Single(); // However this is loaded, whether single row or row per Tenant...
var customer = new Customer
{
// populate values...
PayrollNumber = settings.NextPayrollNumber ;
};
int retryCount = 0;
bool complete = false;
while(retryCount < 5 && !complete)
{
try
{
_context.SaveChanges();
complete = true;
}
catch (SqlException ex)
{
var constraintErrorNumbers = new[] {547, 2601, 2627}; // SQL codes around constraint violations.
if (constraintErrorNumbers.Contains(ex.Number)
{
_context.Entry(settings).Reload(); //Refresh the settings from the DB.
int currentPayrollNumber = customer.PayrollNumber;
customer.PayrollNumber = settings.NextPayrollNumber ;
if(customer.PayrollNumber == currentPayrollNumber)
throw; // It wasn't the payroll number that was duplicated because the sequence hasn't changed.
retryCount ;
}
else
throw;
}
}
您很可能需要捕獲類似 EF InsertException 或 UpdateException 而不是 SqlException 并檢查應該是 SqlException 的 InnerException。
這應該通過成功保存新客戶來更新設定中的 NextPayrollNumber。
通常,我不建議在表格中為工資單號之類的東西保留一個序列,而是生成/選擇一個“應該是唯一的”值,如亂數、雪花或哈希等來構建和驗證新的工資單號。需要應用相同的重試邏輯來處理罕見的重復情況,但這不依賴于對一個序列的協調插入。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/521488.html
上一篇:將具有相同列值的行分組/排序,并按日期DESC對每個組進行排序
下一篇:將SQL陳述句與IN串列結合起來
