首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ ADO 執行 Update 遭遇「當前記錄被鎖定」解決方案

     編輯:VC 教學

錯誤現象

使用 `Recordset::Update` 寫入資料時拋出例外:「無法更新,當前記錄被鎖定」。常見於批次新增/修改大量記錄、並發存取或游標/鎖定類型設定不當。

方案一:交易處理(推薦)

將一組寫入操作包裝在交易中,確保原子性並減少鎖定衝突。


try {
    conn->BeginTrans();
    for (int i = 0; i < n; ++i) {
        rs->AddNew();
        rs->PutCollect("Field1", val1);
        rs->PutCollect("Field2", val2);
        // ... 其他欄位
        rs->Update(); // 單筆寫入
    }
    conn->CommitTrans();
} catch (_com_error& e) {
    conn->RollbackTrans();
    AfxMessageBox(_T("寫入失敗:") + e.ErrorMessage());
}

注意:交易不宜過長,避免長時間持有鎖導致死結。

方案二:改用 INSERT SQL 陳述式

直接執行 `INSERT INTO ...` 避開 Recordset 游標鎖定機制,效能更佳。


CString sql;
sql.Format(_T("INSERT INTO MyTable (F1, F2) VALUES ('%s', %d)"), val1, val2);
conn->Execute(_bstr_t(sql), NULL, adExecuteNoRecords);

方案三:檢查資料格式與空值

  • 欄位型別不符(如字串寫入數值欄位)會觸發轉換錯誤,有時誤報為鎖定。
  • 非空欄位未賦值、自動編號欄位被手動指定值等。
  • 使用 `_variant_t` 封裝資料,自動處理型別轉換與 NULL。

進階建議

  1. 開啟 Recordset 時指定 `adOpenDynamic, adLockOptimistic`(樂觀鎖),僅在 `Update` 瞬間鎖定。
  2. 批次匯入時考慮 `adLockBatchOptimistic` + `UpdateBatch`,一次提交多筆變更。
  3. 檢查資料庫層面:是否有觸發器、檢查約束導致長時間鎖定;索引碎片過多造成頁面鎖定升級。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved