Hiểu Đơn Giản Về Giao Dịch Cơ Sở Dữ Liệu và Tính Chất ACID

07 tháng 4, 2026·5 phút đọc

Bài viết giải thích khái niệm giao dịch cơ sở dữ liệu, cùng bốn tính chất ACID quan trọng giúp đảm bảo tính nhất quán và toàn vẹn dữ liệu trong hệ thống. Các ví dụ SQL và ứng dụng thực tiễn với Node.js và Prisma cũng được minh họa chi tiết.

Hiểu Đơn Giản Về Giao Dịch Cơ Sở Dữ Liệu và Tính Chất ACID

Hiểu Đơn Giản Về Giao Dịch Cơ Sở Dữ Liệu và Tính Chất ACID

Giao dịch cơ sở dữ liệu là tập hợp các thao tác mà tất cả phải thành công hoặc tất cả thất bại cùng lúc, nhằm đảm bảo tính nhất quán dữ liệu trong các hệ thống phức tạp. Bài viết này sẽ giúp bạn hiểu rõ hơn về giao dịch cũng như bốn tính chất cơ bản của ACID: Atomicity (Tính nguyên tử), Consistency (Tính nhất quán), Isolation (Tính cô lập), và Durability (Tính bền vững).

Giao Dịch Là Gì?

Giao dịch (transaction) là một nhóm các thao tác trên cơ sở dữ liệu được thực hiện như một khối đồng nhất. Nếu một thao tác trong nhóm bị lỗi, toàn bộ giao dịch sẽ bị huỷ và dữ liệu trở về trạng thái trước đó, tránh hiện tượng mất dữ liệu hay thông tin không nhất quán.

Ví dụ:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Nếu thao tác cập nhật số dư tài khoản thứ hai không thành công, thao tác đầu tiên cũng sẽ bị hoàn tác, tránh tình trạng tiền "biến mất".

Bốn Tính Chất Cốt Lõi của ACID

1. Atomicity (Tính Nguyên Tử)

Mọi thao tác trong giao dịch phải thực hiện xong toàn bộ hoặc không thực hiện gì cả. Không được phép chỉ thực hiện một phần.

Ví dụ trên đơn hàng:

BEGIN;
INSERT INTO orders (user_id, total) VALUES (42, 9900);
INSERT INTO order_items (order_id, product_id, qty) VALUES (LASTVAL(), 7, 2);
UPDATE inventory SET stock = stock - 2 WHERE product_id = 7;
COMMIT;

Nếu một bước nào đó thất bại, tất cả các thao tác sẽ bị huỷ. Không được phép tồn tại đơn hàng không có mặt hàng hoặc mặt hàng đã trừ kho nhưng đơn chưa tạo.

2. Consistency (Tính Nhất Quán)

Dữ liệu phải hợp lệ trước và sau khi giao dịch. Ràng buộc dữ liệu sẽ ngăn chặn các trạng thái sai lệch hoặc không hợp lệ.

Ví dụ với ràng buộc số dư tài khoản không được âm:

ALTER TABLE accounts ADD CONSTRAINT positive_balance CHECK (balance >= 0);

BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1; -- giả sử số dư tài khoản chỉ còn 500
-- Vi phạm ràng buộc CHECK, giao dịch bị rollback tự động
ROLLBACK;

3. Isolation (Tính Cô Lập)

Các giao dịch đồng thời không thể nhìn thấy dữ liệu chưa được cam kết của nhau. Có 4 mức độ cô lập trong SQL:

  • Read Uncommitted: Có thể đọc được dữ liệu chưa cam kết (dirty read), gây ra sai sót khi giao dịch trước rollback.
  • Read Committed: Mặc định trong PostgreSQL, chỉ đọc được dữ liệu đã cam kết, không có dirty read nhưng có thể xảy ra non-repeatable read (giá trị đọc có thể khác khi truy vấn lại).
  • Repeatable Read: Đảm bảo trong một giao dịch kết quả truy vấn không thay đổi, kể cả khi giao dịch khác cập nhật.
  • Serializable: Mức độ cao nhất, đảm bảo giao dịch thực thi tuần tự, tránh tranh chấp khóa nhưng hiệu năng thấp do tăng cạnh tranh khoá.

4. Durability (Tính Bền Vững)

Sau khi giao dịch được cam kết (COMMIT), dữ liệu sẽ được ghi vĩnh viễn vào ổ đĩa, không bị mất ngay cả khi hệ thống gặp sự cố. PostgreSQL dùng cơ chế WAL (Write-Ahead Log) để bảo vệ tính bền vững này.

Áp Dụng Trong Mã Nguồn

Node.js và Prisma

Prisma hỗ trợ giao dịch với cú pháp dễ dàng, giúp các thao tác được thực thi nguyên tử:

async function transferFunds(fromId: string, toId: string, amount: number) {
  return prisma.$transaction(async (tx) => {
    const sender = await tx.account.findUnique({ where: { id: fromId } });
    if (!sender || sender.balance < amount) {
      throw new Error('Insufficient funds');
    }

    await tx.account.update({
      where: { id: fromId },
      data: { balance: { decrement: amount } },
    });

    await tx.account.update({
      where: { id: toId },
      data: { balance: { increment: amount } },
    });

    await tx.transaction.create({
      data: { fromId, toId, amount, type: 'transfer' },
    });
  });
}

Nếu bất kỳ thao tác nào trong hàm trên lỗi, toàn bộ giao dịch sẽ rollback tự động.

Giao Dịch SQL Thô với Node.js

import { Pool } from 'pg';

async function createOrderWithItems(userId: string, items: OrderItem[]) {
  const client = await pool.connect();

  try {
    await client.query('BEGIN');

    const orderResult = await client.query(
      'INSERT INTO orders (user_id, status) VALUES ($1, $2) RETURNING id',
      [userId, 'pending']
    );
    const orderId = orderResult.rows[0].id;

    for (const item of items) {
      await client.query(
        'INSERT INTO order_items (order_id, product_id, qty, price) VALUES ($1, $2, $3, $4)',
        [orderId, item.productId, item.qty, item.price]
      );
      await client.query(
        'UPDATE inventory SET stock = stock - $1 WHERE product_id = $2',
        [item.qty, item.productId]
      );
    }

    await client.query('COMMIT');
    return orderId;

  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
}

Những Lưu Ý Khi Sử Dụng Giao Dịch

  • Giữ giao dịch ngắn gọn: Giao dịch lâu sẽ giữ khóa trên dữ liệu, làm các giao dịch khác phải chờ gây nghẽn.
  • Tránh lỗi N+1 transaction: Thay vì chạy nhiều giao dịch nhỏ trong vòng lặp (N giao dịch), hãy gom lại thành một giao dịch lớn để tăng hiệu năng và tính nhất quán.

Kết Luận

Giao dịch cơ sở dữ liệu không phải là phép màu mà là một hợp đồng cam kết độ an toàn dữ liệu. Hiểu rõ tính chất ACID giúp bạn xây dựng hệ thống ổn định, xử lý lỗi chính xác hơn trong phát triển phần mềm, đặc biệt với những hệ thống tài chính, thương mại điện tử.


Bạn đang sử dụng Prisma và PostgreSQL? Bộ công cụ SaaS Starter Kit của Whoff Agents AI có tích hợp sẵn tiện ích transaction và locking tối ưu sẵn sàng giúp bạn xây dựng sản phẩm thực tế nhanh hơn.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗