Chuyển tới nội dung chính

Các Chiến lược Khóa trong Cơ sở dữ liệu

Bạn sẽ Học được gì

Kết thúc trang này, bạn sẽ có thể:

  • Giải thích tại sao khóa (Locking) cần thiết trong môi trường cơ sở dữ liệu đồng thời (Concurrent Environment)
  • Nhận diện các loại khóa (chia sẻ, độc quyền, ý định, cập nhật) và các mức độ chi tiết (Granularity) của chúng
  • So sánh khóa bi quan (Pessimistic)khóa lạc quan (Optimistic) — cách hoạt động, khi nào sử dụng, và đánh đổi giữa chúng
  • Nhận diện và ngăn chặn Deadlock (Khóa chết)
  • Hiểu leo thang khóa (Lock Escalation) và tác động đến hiệu năng
  • Chọn chiến lược khóa phù hợp bằng khung quyết định (Decision Framework)

Vấn đề Đồng thời (The Concurrency Problem)

Hãy tưởng tượng một hệ thống đặt vé xem hòa nhạc. Chỉ còn một ghế trống, và hai người dùng cố gắng đặt cùng lúc:

User A: READ seat → status = "available"
User B: READ seat → status = "available"
User A: UPDATE seat → status = "booked by A"
User B: UPDATE seat → status = "booked by B"

Cả hai người dùng đều đọc "available", cả hai đều cập nhật, và ghế bị đặt trùng (Double-booked). Đây là một điều kiện tranh chấp (Race Condition) — và nó xảy ra bất cứ khi nào nhiều giao dịch (Transactions) truy cập cùng dữ liệu đồng thời mà không có sự phối hợp.

Điều gì có thể sai nếu không có khóa?

Vấn đềMô tảVí dụ
Cập nhật bị mất (Lost Update)Hai giao dịch ghi đè thay đổi của nhauCả hai người dùng đặt ghế cuối cùng
Đọc bẩn (Dirty Read)Đọc dữ liệu chưa được commit từ giao dịch khácĐọc số dư giữa quá trình chuyển tiền
Đọc không lặp lại (Non-Repeatable Read)Đọc cùng một dòng hai lần nhận được giá trị khác nhauDòng bị sửa đổi giữa hai lần đọc trong cùng giao dịch
Đọc ma (Phantom Read)Chạy lại truy vấn trả về tập dòng khác nhauDòng mới được chèn giữa các truy vấn

Khóa (Locks) là cơ chế chính mà cơ sở dữ liệu sử dụng để phối hợp truy cập đồng thời và ngăn chặn các vấn đề này.

Khóa Bi quan so với Khóa Lạc quan

Kiến thức Nền tảng về Khóa (Lock Fundamentals)

Trước khi so sánh các chiến lược, hãy hiểu các khối xây dựng cơ bản.

Các loại khóa

Loại khóaPhạm viTương thích vớiMục đích
Shared Lock (S - Khóa chia sẻ)Dòng / Trang / BảngCác khóa chia sẻ khácCho phép đọc đồng thời
Exclusive Lock (X - Khóa độc quyền)Dòng / Trang / BảngKhông khóa nào khácNgăn chặn mọi truy cập đồng thời
Intent Shared (IS - Khóa chia sẻ ý định)BảngCác khóa ý định khácBáo hiệu: "Tôi có thể khóa một dòng ở chế độ chia sẻ"
Intent Exclusive (IX - Khóa độc quyền ý định)BảngKhóa IS, nhưng không với khóa S trên cùng tài nguyênBáo hiệu: "Tôi có thể khóa một dòng ở chế độ độc quyền"
Update Lock (U - Khóa cập nhật)DòngKhóa chia sẻ, nhưng không với khóa U/X khácNgăn Deadlock khi nâng cấp S → X

Ma trận tương thích — khóa nào có thể cùng tồn tại trên cùng một tài nguyên:

         S    X    IS    IX    U
S ✓ ✗ ✓ ✗ ✓
X ✗ ✗ ✗ ✗ ✗
IS ✓ ✗ ✓ ✓ ✓
IX ✗ ✗ ✓ ✓ ✗
U ✓ ✗ ✓ ✗ ✗

Mức độ Chi tiết của Khóa (Lock Granularity)

Việc chọn mức độ chi tiết phù hợp cân bằng giữa tính nhất quán và hiệu năng:

Mức độ chi tiếtPhạm vi khóaTính đồng thờiChi phíTrường hợp sử dụng
Database (Cơ sở dữ liệu)Toàn bộ cơ sở dữ liệuKhôngRất thấpBảo trì, sao lưu
Table (Bảng)Tất cả các dòng trong bảngRất thấpThấpThao tác hàng loạt, thay đổi schema
Page (Trang)Một khối các dòngTrung bìnhTrung bìnhMặc định của một số công cụ cơ sở dữ liệu
Row (Dòng)Một dòng duy nhấtCaoCao hơnHầu hết các thao tác OLTP
mẹo

Luôn áp dụng khóa ở mức độ chi tiết nhất (dòng thay vì bảng) để giảm thiểu tranh chấp và tối đa hóa tính đồng thời.

Vòng đời Khóa (Lock Lifecycle)

Mọi khóa đều tuân theo cùng một vòng đời:

  1. Yêu cầu (Request) — một giao dịch yêu cầu trình quản lý khóa cấp khóa
  2. Được cấp hoặc Bị chặn — nếu tương thích với các khóa hiện có, khóa được cấp; nếu không, giao dịch phải chờ
  3. Đang giữ (Held) — khóa hoạt động trong suốt thời gian của giao dịch
  4. Đã giải phóng (Released) — khóa được giải phóng khi COMMIT hoặc ROLLBACK

Khóa Bi quan (Pessimistic Locking)

Khóa bi quan giả định xung đột sẽ xảy ra. Nó thu nhận khóa trên dữ liệu trước khi thực hiện bất kỳ sửa đổi nào, ngăn chặn các giao dịch khác đọc hoặc sửa đổi dữ liệu bị khóa cho đến khi khóa được giải phóng.

Cách hoạt động (How it works)

Hai giao dịch (Transaction) tranh giành cùng một dòng products (id=1, stock=10). Giao dịch A thu nhận khóa trước — Giao dịch B phải chờ cho đến khi A commit (xác nhận).

Đặc điểm chính: Giao dịch B bị chặn vật lý ở mức cơ sở dữ liệu — nó không thể tiếp tục cho đến khi A giải phóng khóa.

Các lệnh SQL phổ biến

-- Khóa đọc bi quan (khóa chia sẻ)
SELECT * FROM orders WHERE id = 100 LOCK IN SHARE MODE;

-- Khóa ghi bi quan (khóa độc quyền)
SELECT * FROM orders WHERE id = 100 FOR UPDATE;

-- PostgreSQL: khóa cố vấn (Advisory Lock - mức ứng dụng)
SELECT pg_advisory_lock(12345);
SELECT pg_advisory_unlock(12345);

-- SQL Server: khóa dựa trên gợi ý (Hint-based Locking)
SELECT * FROM orders WITH (UPDLOCK, HOLDLOCK) WHERE id = 100;

Khi nào nên sử dụng Khóa Bi quan

  • Mức độ tranh chấp cao (High Contention) — nhiều giao dịch cạnh tranh cho cùng các dòng (ví dụ: đặt vé, quản lý tồn kho)
  • Tính toàn vẹn dữ liệu quan trọng (Critical Data Integrity) — chi phí của một xung đột là không thể chấp nhận được (ví dụ: giao dịch tài chính)
  • Giao dịch ngắn (Short Transactions) — khóa được giữ ngắn, giảm thiểu thời gian chặn
  • Yêu cầu nhất quán thời gian thực (Real-time Consistency) — người dùng phải thấy trạng thái cập nhật nhất

Nhược điểm

  • Giảm tính đồng thời (Reduced Concurrency) — các giao dịch khác bị chặn trong khi khóa được giữ
  • Deadlock (Khóa chết) — hai giao dịch chờ khóa của nhau vô thời hạn
  • Nút thắt hiệu năng (Performance Bottleneck) — các giao dịch chạy lâu giữ khóa và chặn toàn bộ hệ thống

Khóa Lạc quan (Optimistic Locking)

Khóa lạc quan giả định xung đột là hiếm. Nó cho phép nhiều giao dịch đọc và sửa đổi dữ liệu đồng thời mà không cần thu nhận khóa trước. Thay vào đó, nó kiểm tra xung đột tại thời điểm commit. Nếu phát hiện xung đột, giao dịch được hoàn tác và phải thử lại.

Cách hoạt động

Khóa lạc quan thường sử dụng cột phiên bản (Version Column) hoặc cột dấu thời gian (Timestamp Column) để phát hiện xung đột:

Transaction A:                          Transaction B:
Đọc sản phẩm (version = 1)
Đọc sản phẩm (version = 1)
Cập nhật: SET stock = stock - 1,
version = version + 1
WHERE id = 1 AND version = 1
→ 1 dòng được cập nhật ✓
Cập nhật: SET stock = stock - 1,
version = version + 1
WHERE id = 1 AND version = 1
→ 0 dòng được cập nhật ✗ (version giờ là 2)
→ Phát hiện xung đột, thử lại hoặc hủy

Đặc điểm chính: Không có khóa nào được giữ — Giao dịch B tiến hành tự do và chỉ phát hiện xung đột khi cố gắng commit.

Các cách triển khai

1. Cột phiên bản (Version Column - khuyến nghị)

-- Thêm cột phiên bản
ALTER TABLE products ADD COLUMN version INT DEFAULT 0;

-- Đọc
SELECT id, stock, version FROM products WHERE id = 1;
-- Trả về: id=1, stock=10, version=3

-- Cập nhật (kiểm tra phiên bản)
UPDATE products
SET stock = stock - 1, version = version + 1
WHERE id = 1 AND version = 3;
-- Nếu rowcount = 1 → thành công
-- Nếu rowcount = 0 → xung đột, giao dịch khác đã sửa đổi

2. Cột dấu thời gian (Timestamp Column)

-- Thêm cột dấu thời gian
ALTER TABLE products ADD COLUMN modified_at TIMESTAMP DEFAULT NOW();

-- Đọc
SELECT id, stock, modified_at FROM products WHERE id = 1;

-- Cập nhật (kiểm tra dấu thời gian)
UPDATE products
SET stock = stock - 1, modified_at = NOW()
WHERE id = 1 AND modified_at = '2025-01-15 10:30:00';
-- Nếu rowcount = 0 → phát hiện xung đột

3. Checksum cột (Xác minh tất cả các cột)

-- Cập nhật kiểm tra tất cả giá trị gốc
UPDATE products
SET stock = stock - 1
WHERE id = 1
AND stock = 10 -- giá trị gốc
AND name = 'Widget' -- giá trị gốc
AND price = 9.99; -- giá trị gốc
-- Nếu rowcount = 0 → có gì đó đã thay đổi, xung đột

Khóa lạc quan trong EF Core

// Cấu hình Token đồng thời (Concurrency Token)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(p => p.Version)
.IsRowVersion()
.IsConcurrencyToken();
}

// Sử dụng với logic thử lại
var maxRetries = 3;
for (var i = 0; i < maxRetries; i++)
{
try
{
var product = await context.Products.FindAsync(id);
product.Stock -= 1;
await context.SaveChangesAsync();
break; // thành công
}
catch (DbUpdateConcurrencyException)
{
if (i == maxRetries - 1) throw;
// Tách các thực thể cũ và thử lại
foreach (var entry in context.ChangeTracker.Entries())
entry.State = EntityState.Detached;
}
}

Khi nào nên sử dụng Khóa Lạc quan

  • Mức độ tranh chấp thấp (Low Contention) — xung đột hiếm khi xảy ra (ví dụ: cập nhật hồ sơ người dùng, chỉnh sửa wiki)
  • Khối lượng đọc cao (High Read Volume) — nhiều lần đọc, ít lần ghi vào cùng các dòng
  • Hệ thống phân tán (Distributed Systems) — khóa giữa các dịch vụ là không thực tế
  • Giao dịch dài (Long Transactions) — giữ khóa bi quan trong thời gian dài là tốn kém

Nhược điểm

  • Chi phí thử lại (Retry Overhead) — các giao dịch thất bại phải được thử lại bởi ứng dụng
  • Công việc lãng phí (Wasted Work) — giao dịch thực hiện tất cả công việc rồi mới phát hiện xung đột
  • Không phù hợp khi tranh chấp cao — thử lại thường xuyên làm mất đi lợi ích hiệu năng

Trực quan Tương tác (Interactive Visualization)

Xem cách khóa bi quan và lạc quan xử lý hai giao dịch đồng thời cạnh tranh cho cùng một dòng. Chuyển đổi giữa các chiến lược để thấy sự khác biệt.

Lock data before modifying — other transactions are BLOCKED until the lock is released. Prevents conflicts but reduces concurrency.

0 / 7
Transaction A
Idle
🗄️Database Row
id1
stock10
Transaction B
Idle

Deadlock (Khóa chết)

Deadlock xảy ra khi hai giao dịch mỗi giao dịch giữ một khóa mà giao dịch kia cần — không bên nào có thể tiếp tục.

Phát hiện và Giải quyết

Hầu hết cơ sở dữ liệu phát hiện Deadlock tự động bằng cách kiểm tra vòng chờ tuần hoàn (Circular Wait) trong đồ thị khóa. Khi tìm thấy, cơ sở dữ liệu:

  1. Chọn một giao dịch nạn nhân (Victim Transaction) (thường là giao dịch đã thực hiện ít công việc nhất)
  2. Hoàn tác (Rollback) nó và giải phóng các khóa
  3. Trả về lỗi cho ứng dụng (ví dụ: mã lỗi 1205 trong SQL Server)

Ứng dụng phải bắt lỗi này và thử lại giao dịch.

Chiến lược Ngăn chặn

Chiến lượcCách hoạt độngHiệu quả
Thứ tự khóa nhất quán (Consistent Lock Ordering)Luôn thu nhận khóa theo cùng thứ tự trong tất cả các giao dịchLoại bỏ vòng chờ — phòng ngừa hiệu quả nhất
Giao dịch ngắn (Short Transactions)Giảm thiểu thời gian giữa lúc thu nhận và giải phóng khóaGiảm cửa sổ hình thành Deadlock
Thời gian chờ khóa (Lock Timeouts)Đặt lock_timeout để giao dịch không chờ vô thời hạnNgăn chặn chặn vô thời hạn, nhưng không ngăn Deadlock
Mức cô lập thấp hơn (Lower Isolation Levels)Sử dụng mức cô lập yếu nhất đáp ứng yêu cầuGiảm số lượng và thời gian giữ khóa
cảnh báo

Với khóa bi quan, luôn triển khai logic thử lại Deadlock trong ứng dụng của bạn. Deadlock không phải là lỗi — chúng là điều bình thường trong các hệ thống đồng thời.

Leo thang Khóa (Lock Escalation)

Leo thang khóa (Lock Escalation) là khi cơ sở dữ liệu chuyển đổi nhiều khóa chi tiết (mức dòng) thành khóa thô hơn (mức trang hoặc mức bảng) để giảm chi phí bộ nhớ.

Tại sao nó xảy ra

Quản lý hàng nghìn khóa dòng riêng biệt tiêu tốn bộ nhớ đáng kể. Khi một giao dịch vượt quá ngưỡng, cơ sở dữ liệu thực hiện leo thang:

  • SQL Server leo thang ở khoảng 5,000 khóa mỗi đối tượng
  • PostgreSQL sử dụng cách tiếp cận khác — nó không leo thang mà sử dụng khóa vị từ (Predicate Locks) cho mức cô lập có thể tuần tự hóa (Serializable)

Tác động

  • Giảm chi phí quản lý khóa và sử dụng bộ nhớ
  • Giảm tính đồng thời — các truy vấn không liên quan trên cùng bảng có thể bị chặn
  • Có thể gây giảm hiệu năng bất ngờ trong các khối lượng công việc OLTP

Cách quản lý

  • Chia các thao tác hàng loạt lớn thành các phần nhỏ hơn — xử lý 1,000 dòng mỗi lần thay vì 100,000
  • Sử dụng mức cô lập phù hợp — không cô lập quá mức cần thiết
  • Giám sát số lượng khóa — sử dụng sys.dm_tran_locks (SQL Server) hoặc pg_locks (PostgreSQL)
  • SQL Server: sử dụng ALTER TABLE ... SET (LOCK_ESCALATION = DISABLE) một cách thận trọng — ngăn leo thang nhưng có thể tăng áp lực bộ nhớ

Khóa Bi quan vs Khóa Lạc quan: So sánh

Bảng so sánh

Khóa Bi quan (Pessimistic)Khóa Lạc quan (Optimistic)
Giả địnhXung đột sẽ xảy raXung đột là hiếm
Thời điểm khóaTrước khi đọc/sửa đổiChỉ kiểm tra khi commit
ChặnCó — các giao dịch khác phải chờKhông — các giao dịch tự do tiến hành
Xử lý xung độtNgăn chặn (chặn cho đến khi an toàn)Phát hiện (hoàn tác và thử lại)
Tính đồng thờiThấp hơn (truy cập tuần tự)Cao hơn (truy cập song song)
Rủi ro DeadlockCó (cần thứ tự khóa)Không (không giữ khóa)
Phù hợp nhất choTranh chấp cao, dữ liệu quan trọngTranh chấp thấp, nặng về đọc
Triển khaiMức cơ sở dữ liệu (FOR UPDATE)Mức ứng dụng (cột phiên bản)
Hiệu năngCó thể giảm dưới tảiThông lượng tốt hơn, chi phí thử lại khi xung đột

Hướng dẫn Quyết định

Sử dụng biểu đồ sau để chọn chiến lược phù hợp cho kịch bản của bạn:

Các Lỗi Phổ biến

  • Giữ khóa quá lâu — các giao dịch chạy lâu với khóa bi quan chặn người dùng khác và giảm hiệu năng. Giữ giao dịch ngắn.
  • Leo thang khóa (Lock Escalation) — cơ sở dữ liệu có thể leo thang khóa dòng thành khóa bảng khi nhiều dòng bị khóa. Điều này có thể làm giảm tính đồng thời bất ngờ.
  • Thiếu logic thử lại — khóa lạc quan không có logic thử lại gây lỗi hiển thị cho người dùng thay vì phục hồi trong suốt.
  • Bỏ qua Deadlock — với khóa bi quan, luôn triển khai phát hiện Deadlock và logic thử lại trong ứng dụng của bạn.
  • Sử dụng SELECT FOR UPDATE cho đọc — chỉ sử dụng khi bạn có ý định sửa đổi. Khóa độc quyền không cần thiết làm giảm tính đồng thời.

Best Practices

  1. Giữ khóa trong thời gian tối thiểu — giảm tranh chấp bằng cách giữ giao dịch ngắn
  2. Khóa ở mức độ chi tiết nhất — ưu tiên khóa mức dòng thay vì mức bảng
  3. Triển khai logic thử lại — xử lý lỗi đồng thời lạc quan và Deadlock một cách khéo léo
  4. Chọn chiến lược phù hợp — bi quan cho dữ liệu quan trọng có tranh chấp cao, lạc quan cho kịch bản tranh chấp thấp
  5. Giám sát thời gian chờ khóa (Lock Waits) — sử dụng giám sát cơ sở dữ liệu để phát hiện các điểm nóng tranh chấp khóa
  6. Sử dụng mức cô lập (Isolation Level) phù hợp — khớp mức cô lập với yêu cầu nhất quán của bạn

Câu hỏi Phỏng vấn

1. Sự khác biệt giữa Khóa Bi quan và Khóa Lạc quan là gì?

Khóa Bi quan (Pessimistic)Khóa Lạc quan (Optimistic)
Chiến lượcNgăn chặn xung đột bằng cách khóa dữ liệu trướcPhát hiện xung đột tại thời điểm commit
Cơ chếKhóa cơ sở dữ liệu (FOR UPDATE, LOCK IN SHARE MODE)Cột phiên bản (Version Column), dấu thời gian (Timestamp), hoặc băm dòng (Row Hash)
Khi xung đột xảy raCác giao dịch khác bị chặnGiao dịch thua bị hoàn tác
Phù hợp nhất choTranh chấp cao, dữ liệu quan trọngTranh chấp thấp, khối lượng công việc nặng về đọc
Đánh đổiTính đồng thời thấp hơn, tính nhất quán mạnh hơnTính đồng thời cao hơn, chi phí thử lại khi xung đột

2. Khi nào bạn chọn Khóa Bi quan thay vì Khóa Lạc quan?

Chọn Khóa Bi quan khi:

  • Mức độ tranh chấp cao (High Contention) — nhiều người dùng thường xuyên cập nhật cùng các dòng (ví dụ: đặt vé, trừ tồn kho)
  • Tính toàn vẹn dữ liệu là quan trọng (Data Integrity is Critical) — nghiệp vụ không thể chấp nhận cập nhật bị mất (ví dụ: chuyển tiền tài khoản ngân hàng)
  • Xung đột tốn kém (Conflicts are Expensive) — thử lại toàn bộ thao tác tốn kém hơn việc chặn (ví dụ: tính toán phức tạp trước khi cập nhật)
  • Giao dịch ngắn (Short Transactions) — khóa được giữ ngắn, nên thời gian chặn là tối thiểu

3. Khóa Lạc quan phát hiện xung đột như thế nào?

Khóa lạc quan phát hiện xung đột bằng cách kiểm tra dữ liệu không bị thay đổi kể từ khi đọc:

  1. Đọc dòng cùng với số phiên bản (Version Number) (hoặc dấu thời gian)
  2. Khi cập nhật, bao gồm điều kiện WHERE version = <phiên_bản_gốc>
  3. Kiểm tra số dòng (Row Count) của lần cập nhật:
    • rowcount = 1 → không có xung đột, cập nhật thành công, phiên bản được tăng
    • rowcount = 0 → phát hiện xung đột, giao dịch khác đã sửa đổi dòng trước
  4. Khi có xung đột, ứng dụng phải thử lại (Retry) hoặc hủy (Abort) thao tác

4. Deadlock là gì và làm sao để ngăn chặn?

Deadlock (Khóa chết) xảy ra khi hai giao dịch mỗi giao dịch giữ một khóa mà giao dịch kia cần, tạo ra một vòng chờ tuần hoàn:

Transaction A: khóa Dòng 1, đang chờ Dòng 2
Transaction B: khóa Dòng 2, đang chờ Dòng 1
→ Không bên nào có thể tiếp tục → Deadlock

Chiến lược ngăn chặn:

  • Thứ tự khóa nhất quán (Consistent Lock Ordering) — luôn thu nhận khóa theo cùng thứ tự trong tất cả các giao dịch
  • Giao dịch ngắn (Short Transactions) — giảm thiểu thời gian giữ khóa
  • Mức cô lập thấp hơn (Lower Isolation Levels) — sử dụng mức cô lập yếu nhất đáp ứng yêu cầu của bạn
  • Thời gian chờ khóa (Lock Timeouts) — đặt lock_timeout để giao dịch không chờ vô thời hạn
  • Logic thử lại (Retry Logic) — bắt lỗi Deadlock và thử lại giao dịch

Hầu hết cơ sở dữ liệu phát hiện Deadlock tự động và hủy một giao dịch (giao dịch "nạn nhân") để phá vỡ chu trình.

5. Làm thế nào để triển khai Khóa Lạc quan trong EF Core?

// Cấu hình Token đồng thời (Concurrency Token)
modelBuilder.Entity<Product>()
.Property(p => p.Version)
.IsRowVersion(); // SQL Server: rowversion; PostgreSQL: xmin

// Hoặc sử dụng token đồng thời thủ công
modelBuilder.Entity<Product>()
.Property(p => p.Version)
.IsConcurrencyToken();

// Xử lý DbUpdateConcurrencyException với thử lại
try
{
product.Stock -= 1;
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException ex)
{
// Tùy chọn 1: Tải lại và thử lại
await ex.Entries.Single().ReloadAsync();
// Tùy chọn 2: Giải quyết thủ công (hợp nhất thay đổi)
// Tùy chọn 3: Để người dùng quyết định
}

6. Leo thang khóa (Lock Escalation) là gì và tại sao nó quan trọng?

Leo thang khóa (Lock Escalation) là khi cơ sở dữ liệu chuyển đổi nhiều khóa chi tiết (mức dòng) thành khóa thô hơn (mức trang hoặc mức bảng) để giảm chi phí bộ nhớ.

Tại sao nó quan trọng:

  • Giảm chi phí quản lý khóa nhưng giảm tính đồng thời
  • Có thể gây chặn bất ngờ các truy vấn không liên quan
  • Được kích hoạt khi một giao dịch vượt quá ngưỡng khóa (ví dụ: SQL Server leo thang ở khoảng ~5,000 khóa)

Cách quản lý:

  • Chia các thao tác hàng loạt lớn thành các phần nhỏ hơn
  • Sử dụng mức cô lập phù hợp
  • Trong SQL Server: sử dụng ALTER TABLE ... SET (LOCK_ESCALATION = DISABLE) một cách thận trọng
  • Giám sát với sys.dm_tran_locks (SQL Server) hoặc pg_locks (PostgreSQL)

Tìm hiểu thêm