Giải thích về giao dịch SQL và ACID: Các mức CAM KẾT, ROLLBACK và Cô lập

  1. Trang chủ
  2. Blog
  3. Cơ sở dữ liệu & SQL

Cơ sở dữ liệu & SQL

Giải thích về giao dịch SQL và ACID: Các mức CAM KẾT, ROLLBACK và Cô lập

Điều gì xảy ra nếu máy chủ bị lỗi giữa chừng khi chuyển tiền giữa hai tài khoản? Giao dịch là câu trả lời. Xem cách chúng hoạt động trên một ví dụ thực tế, ACID nghĩa là gì và cách chọn mức cách ly.

Đọc 9 phút
Các giao dịch SQL và ACID được giải thích: CAM KẾT, ROLLBACK và các mức cô lập

Điểm chính

  • Một giao dịch nhóm các câu lệnh sao cho tất cả chúng cùng thành công hoặc tất cả đều thất bại cùng nhau.
  • COMMIT thực hiện các thay đổi vĩnh viễn và ROLLBACK hủy chúng.
  • ACID là viết tắt của tính nguyên tử, tính nhất quán, sự cô lập và độ bền.
  • Sự cách ly mạnh hơn sẽ ngăn ngừa nhiều điểm bất thường hơn, nhưng nó có thể làm giảm khả năng xử lý đồng thời, vì vậy hãy thận trọng lựa chọn.

Việc chuyển 300 rupee từ Asha sang Ben cần hai lần cập nhật: trừ đi một tài khoản và thêm vào tài khoản kia. Nếu hệ thống giữa chúng bị lỗi, tiền sẽ biến mất. Giao dịch SQL tồn tại để biến điều đó thành không thể, bằng cách coi cả hai bước là một đơn vị.

Trong hướng dẫn này, chúng tôi xem xét các cam kết, hoàn tác và lỗi trên một bảng tài khoản nhỏ. Chúng tôi đã chạy các ví dụ đó trong SQLite và số dư được hiển thị là từ lần chạy đó. Các lệnh cơ bản giống nhau trên các cơ sở dữ liệu, nhưng hành vi khóa và cách ly khác nhau rất nhiều, vì vậy chúng tôi chỉ ra nơi để kiểm tra tài liệu cơ sở dữ liệu của riêng bạn.

Giao dịch là gì?

Giao dịch là một chuỗi gồm một hoặc nhiều câu lệnh SQL mà cơ sở dữ liệu xử lý như một thao tác logic đơn lẻ. Đây là bảng của chúng tôi:

CREATE TABLE accounts (
  id INT PRIMARY KEY,
  owner TEXT,
  balance INT CHECK (balance >= 0)
);

INSERT INTO accounts VALUES (1, 'Asha', 1000), (2, 'Ben', 200);

Ràng buộc CHECK là quy tắc mà số dư không bao giờ có thể xuống dưới 0, quy tắc này chúng ta sẽ sử dụng sau. Lưu ý rằng cú pháp để bắt đầu giao dịch khác nhau: SQLite và PostgreSQL chấp nhận BEGIN, MySQL cũng có START TRANSACTION và SQL Server sử dụng BEGIN TRANSACTION.

Bên ngoài một giao dịch rõ ràng, hầu hết các cơ sở dữ liệu đều sử dụng autocommit, trong đó mỗi câu lệnh được lưu ngay khi nó kết thúc. Oracle là một ngoại lệ đáng chú ý, bởi vì phiên đó vẫn ở trong giao dịch cho đến khi bạn cam kết.

CAM KẾT: làm cho nó vĩnh viễn

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

-- Asha | 700
-- Ben  | 500

Cho đến khi COMMIT chạy, những thay đổi này chỉ là tạm thời. Khi nó trả về thành công, cơ sở dữ liệu đảm bảo rằng chúng được lưu. Tổng số trên cả hai tài khoản vẫn ở mức 1200, đó là toàn bộ mục đích của bài tập.

ROLLBACK: hủy bỏ mọi thứ

ROLLBACK hoàn tác mọi thứ kể từ khi giao dịch bắt đầu:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
SELECT owner, balance FROM accounts;
-- Asha | 600   (visible inside this transaction)
-- Ben  | 500

ROLLBACK;
SELECT owner, balance FROM accounts;
-- Asha | 700   (back to where it was)
-- Ben  | 500

Việc khôi phục cũng tự động xảy ra nếu kết nối bị ngắt hoặc máy chủ gặp sự cố trước khi bạn thực hiện, do đó giao dịch đã hoàn thành một nửa sẽ không tồn tại được.

Khi một tuyên bố thất bại

Đây là một trường hợp thực tế hơn. Asha cố gắng gửi 5000 nhưng tài khoản không giữ được. Khoản ghi có cho Ben chạy trước và sau đó khoản ghi nợ phá vỡ quy tắc CHECK:

BEGIN;
UPDATE accounts SET balance = balance + 5000 WHERE id = 2;
UPDATE accounts SET balance = balance - 5000 WHERE id = 1;
-- error: CHECK constraint failed: balance >= 0

ROLLBACK;

-- Asha | 700
-- Ben  | 500

Nếu không có giao dịch, Ben sẽ giữ lại 5000 và sổ sách sẽ sai. Hãy lưu ý một chi tiết quan trọng: một tuyên bố không thành công không phải lúc nào cũng tự hủy giao dịch. Ví dụ: trong SQLite và MySQL, các câu lệnh trước đó có thể vẫn đang chờ xử lý, do đó mã của bạn phải đưa ra lệnh khôi phục. Thay vào đó, PostgreSQL đánh dấu toàn bộ giao dịch là bị hủy bỏ và từ chối các báo cáo tiếp theo cho đến khi bạn quay lại.

Trong mã ứng dụng, luôn ghép nối giao dịch với việc xử lý lỗi. Đây là ý tưởng trong Python và hướng dẫn của chúng tôi về Xử lý ngoại lệ Python giải thích cú pháp:

try:
    conn.execute("BEGIN")
    conn.execute(debit_sql, values)
    conn.execute(credit_sql, values)
    conn.execute("COMMIT")
except Exception:
    conn.execute("ROLLBACK")
    raise

Điểm lưu

Điểm lưu trữ đánh dấu một vị trí bên trong giao dịch, do đó bạn chỉ có thể hoàn tác một phần công việc:

BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 1;
SAVEPOINT bonus;
UPDATE accounts SET balance = balance + 999 WHERE id = 2;
ROLLBACK TO bonus;
UPDATE accounts SET balance = balance + 50 WHERE id = 2;
COMMIT;

-- Asha | 650
-- Ben  | 550

Phần thưởng 999 đã được hoàn tác, trong khi phần còn lại của giao dịch vẫn được tiếp tục và cam kết. Điều này rất hữu ích cho các bước tùy chọn trong một quá trình dài.

Thuộc tính ACID được giải thích

Tài sản Lời hứa Trong chuyển khoản của chúng tôi
Tính nguyên tử Tất cả hoặc không có gì Cả hai bản cập nhật đều xảy ra hoặc không xảy ra
tính nhất quán Quy tắc vẫn giữ sau đó Không có sự cân bằng nào có thể phá vỡ quy tắc CHECK
Cách ly Công việc đồng thời không can thiệp Những người khác không thấy chuyển khoản đã hoàn thành một nửa
Độ bền Dữ liệu đã cam kết vẫn tồn tại thất bại Cắt điện sau COMMIT chẳng mất gì

Tính nhất quán thường bị hiểu lầm. Cơ sở dữ liệu chỉ thực thi các quy tắc bạn khai báo, chẳng hạn như các ràng buộc và khóa ngoại. Nó sẽ không ngăn mã của bạn chuyển sai số tiền. Độ bền thường đạt được nhờ nhật ký ghi trước, trong đó các thay đổi được ghi lại một cách an toàn trên đĩa trước khi cam kết được xác nhận.

Điều gì xảy ra với các giao dịch đồng thời?

Chúng tôi đã mở hai kết nối tới một tệp SQLite. Người đầu tiên bắt đầu giao dịch và cập nhật một hàng từ 1 lên 2 mà chưa cam kết. Đây là những gì kết nối thứ hai nhìn thấy:

Connection B reads:   1                     -- no uncommitted data
Connection B writes:  database is locked    -- it has to wait
(A commits)
Connection B reads:   2                     -- now it sees the change

SQLite chỉ cho phép một người ghi tại một thời điểm, điều này đơn giản hơn cơ sở dữ liệu máy chủ, nơi nhiều giao dịch có thể ghi các hàng khác nhau cùng một lúc. Nhưng nguyên tắc là như nhau: các phiên khác sẽ không thấy những thay đổi không được cam kết trong cài đặt thông thường và các lần ghi xung đột phải chờ. Trong thử nghiệm của chúng tôi, chúng tôi đặt kết nối thứ hai dừng ngay lập tức thay vì chờ đợi, do đó lỗi xuất hiện ngay lập tức.

Đọc bất thường

Khi các giao dịch chồng chéo, một số vấn đề nhất định có thể xảy ra. Tiêu chuẩn SQL xác định những điều này theo những gì một giao dịch có thể quan sát được:

sự bất thường Chuyện gì xảy ra
đọc bẩn Bạn đọc một thay đổi mà một giao dịch khác chưa được cam kết và sau đó nó có thể được khôi phục
Đọc không lặp lại Bạn đọc một hàng hai lần trong một giao dịch và nhận được các giá trị khác nhau, bởi vì ai đó đã cam kết ở giữa
Đọc ảo Bạn chạy cùng một truy vấn hai lần và nhận được các hàng thừa hoặc thiếu vì ai đó đã chèn hoặc xóa một số hàng

Một vấn đề khác là mất bản cập nhật. Hai phiên đọc số dư 100, mỗi phiên thêm 10 và mỗi phiên ghi 110. Một bản cập nhật thực sự đã biến mất khi câu trả lời phải là 120.

Các mức cô lập SQL

Mức cô lập cho phép bạn đánh đổi tính nghiêm ngặt để lấy tính đồng thời. Đây là những gì tiêu chuẩn SQL cho phép ở mỗi cấp độ:

Cấp độ đọc bẩn Đọc không lặp lại Đọc ảo
Đọc không cam kết Có thể Có thể Có thể
Đọc cam kết ngăn chặn Có thể Có thể
Đọc lặp lại ngăn chặn ngăn chặn Có thể
Có thể tuần tự hóa ngăn chặn ngăn chặn ngăn chặn
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Cú pháp và hành vi chính xác phụ thuộc vào cơ sở dữ liệu của bạn. Các giá trị mặc định cũng khác nhau: PostgreSQL và SQL Server sử dụng chế độ đọc cam kết, trong khi InnoDB của MySQL sử dụng chế độ đọc lặp lại. Một số cơ sở dữ liệu đưa ra những đảm bảo mạnh mẽ hơn mức yêu cầu của tiêu chuẩn hoặc coi cấp độ này như cấp độ khác. Ví dụ: trong PostgreSQL, đọc hoạt động không được cam kết giống như đọc đã cam kết. Luôn đọc tài liệu cơ sở dữ liệu của bạn trước khi dựa vào một hành vi cụ thể.

Mẹo: Đối với trường hợp cập nhật bị mất, hãy thực hiện thay đổi trong một câu lệnh, như trong UPDATE accounts SET balance = balance + 10. Thực hiện phép tính trong ứng dụng của bạn từ lần đọc trước đó là điều sẽ mở ra khoảng cách.

Bế tắc

Sự bế tắc 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. Giao dịch A khóa hàng 1 và muốn hàng 2, trong khi giao dịch B khóa hàng 2 và muốn hàng 1. Cả hai đều không thể tiếp tục.

Các cơ sở dữ liệu như PostgreSQL, MySQL và SQL Server phát hiện điều này và hủy một giao dịch do lỗi. Đó là hành vi bình thường và ứng dụng của bạn nên được chuẩn bị cho điều đó. Để giảm tình trạng bế tắc, hãy luôn cập nhật các hàng theo thứ tự nhất quán, chẳng hạn như ID tài khoản thấp nhất trước, giữ giao dịch ngắn gọn và thử lại khi một người được chọn làm nạn nhân.

Các phương pháp hay nhất

  • Giữ giao dịch ngắn gọn. Giao dịch dài giữ khóa và chặn người dùng khác.
  • Không bao giờ đợi người dùng hoặc API chậm trong giao dịch. Hãy thực hiện công việc đó trước khi bạn bắt đầu hoặc sau đó.
  • Luôn xử lý lỗi. Mọi đường dẫn phải kết thúc bằng một cam kết hoặc khôi phục.
  • Thêm các ràng buộc. Chúng cung cấp cho cơ sở dữ liệu các quy tắc thực tế để thực thi. Thiết kế bảng tốt cũng hữu ích.
  • Sử dụng chỉ mục tốt. Tra cứu nhanh hơn có nghĩa là các khóa được giữ trong thời gian ngắn hơn.
  • Hãy cẩn thận khi thử lại. Thử lại khi bế tắc, nhưng hãy đảm bảo rằng một thao tác không thể áp dụng hai lần.
  • Kiểm tra tính đồng thời có mục đích. Nhiều lỗi trong số này chỉ xuất hiện khi tải, do đó, chỉ riêng các thử nghiệm tích hợp cơ bản có thể không phát hiện ra chúng.

Lời kết

Các giao dịch biến một số bước rủi ro thành một hoạt động an toàn và ACID mô tả những đảm bảo khiến điều này trở nên đáng tin cậy. Bất cứ khi nào một hành động kinh doanh chạm vào nhiều hàng hoặc bảng, hãy tự hỏi điều gì sẽ xảy ra nếu nó dừng lại giữa chừng. Nếu câu trả lời làm bạn lo lắng, hãy gói nó vào một giao dịch. Để thực hành, hãy mở hai phiên trong cơ sở dữ liệu cục bộ và cố gắng tự tạo ra các điểm bất thường.

Câu hỏi thường gặp

Giao dịch trong SQL là gì?

Giao dịch là một nhóm các câu lệnh SQL được coi là một đơn vị. Tất cả chúng đều được lưu bằng COMMIT hoặc tất cả chúng được hoàn tác bằng ROLLBACK.

Thuộc tính ACID trong cơ sở dữ liệu là gì?

ACID là viết tắt của tính nguyên tử, tính nhất quán, sự cô lập và độ bền. Cùng nhau, họ đảm bảo các giao dịch là tất cả hoặc không có gì, giữ nguyên các quy tắc, không can thiệp và tồn tại khi xảy ra thất bại.

Sự khác biệt giữa CAM KẾT và ROLLBACK là gì?

COMMIT lưu vĩnh viễn tất cả các thay đổi được thực hiện trong giao dịch. ROLLBACK hủy chúng và trả lại dữ liệu về trạng thái trước khi giao dịch bắt đầu.

Đọc bẩn là gì?

Đọc bẩn là khi một giao dịch đọc thay đổi một giao dịch khác chưa được cam kết. Nếu giao dịch khác quay trở lại, dữ liệu đã đọc chưa bao giờ thực sự tồn tại.

Tôi nên sử dụng mức cách ly nào?

Bắt đầu với mặc định của cơ sở dữ liệu của bạn, điều này thường ổn. Sử dụng tính năng có thể tuần tự hóa cho logic quan trọng trong đó các điểm bất thường không thể chấp nhận được và sẵn sàng thử lại các giao dịch không thành công.

Tiếp tục học hỏi

Làm việc với Stack Quora

Cần trợ giúp về kiểm tra, WordPress hoặc SEO?

Chúng tôi giúp các nhóm phát triển phần mềm tốt hơn và phát triển trang web của họ. Hãy cho chúng tôi biết bạn đang làm gì và chúng tôi sẽ đề xuất bước tiếp theo rõ ràng.

Tiếp tục đọc

Thêm hướng dẫn về thử nghiệm, AI và phát triển hiện đại

Bạn thích bài viết này? Chọn một chủ đề và chuyển ngay sang phần hướng dẫn mới nhất của chúng tôi.

Trí tuệ nhân tạo

Giải thích về ảo giác AI: Tại sao các mô hình ngôn ngữ lại tạo nên mọi thứ và cách giảm thiểu nó

Ảo giác AI đã giải thích: chúng là gì, tại sao mô hình ngôn ngữ tạo ra chúng, các loại phổ biến, cách giảm thiểu chúng bằng cách căn cứ và nhắc nhở …

Đọc bài viết →
DevOps

Giải thích về các biến môi trường: Tệp .env, bí mật và cấu hình được thực hiện đúng

Các biến môi trường được giải thích bằng các ví dụ Python mà chúng tôi đã chạy: đọc và thiết lập chúng, tại sao mọi giá trị đều là một chuỗi, tệp .e…

Đọc bài viết →
Phát triển phần mềm

Giải thích về giới hạn tỷ lệ API: Thuật toán, tiêu đề và xử lý lỗi 429

Giới hạn tốc độ API được giải thích bằng mô phỏng mà chúng tôi đã chạy: nhóm mã thông báo, cửa sổ cố định, cửa sổ trượt, 429 phản hồi, tiêu đề giới …

Đọc bài viết →
Tự động hóa kiểm thử

Chế giễu bằng Python: unittest.mock, patch và những sai lầm khiến bài kiểm tra nói dối

Mô phỏng bằng Python với unittest.mock, đã được thử nghiệm: Mock và return_value, side_effect, vá lỗi nơi sử dụng tên, thông số kỹ thuật và thông số…

Đọc bài viết →
Kiểm thử phần mềm

Giải thích về phạm vi bảo hiểm của mã: Phạm vi tuyến so với chi nhánh và ý nghĩa thực sự 100%

Phạm vi bảo hiểm mã được giải thích bằng cách chạy phạm vi bảo hiểm thực tế: phạm vi bảo hiểm dòng, chi nhánh và điều kiện, đọc báo cáo, lý do tại s…

Đọc bài viết →
Cơ sở dữ liệu & SQL

DELETE vs TRUNCATE vs DROP trong SQL: Sự khác biệt, khôi phục và thời điểm sử dụng mỗi loại

DELETE vs TRUNCATE vs DROP được giải thích bằng SQL đã được thử nghiệm: mỗi loại loại bỏ, khôi phục, kích hoạt, đặt lại danh tính, tốc độ và Postgre…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về Chế độ xem SQL: Tạo, sử dụng và tránh những cạm bẫy, kèm theo ví dụ

Chế độ xem SQL được giải thích bằng các truy vấn chúng tôi đã chạy: tạo chế độ xem, kết quả trực tiếp, ẩn cột, hiệu suất, chế độ xem có thể cập nhật…

Đọc bài viết →
Phát triển phần mềm

Giao diện TypeScript so với loại: Sự khác biệt thực sự, được thử nghiệm bằng trình biên dịch

Giao diện TypeScript so với loại, được kiểm tra bằng trình biên dịch thực: cả hai có thể làm gì, chỉ một người có thể làm gì, hợp nhất khai báo, mở …

Đọc bài viết →
Phát triển phần mềm

Giải thích về Python *args và **kwargs: Hàm linh hoạt với ví dụ rõ ràng

Python *args và **kwargs được giải thích bằng mã chúng tôi đã chạy: đóng gói và giải nén, thứ tự tham số, đối số chỉ từ khóa và chỉ vị trí, trình tr…

Đọc bài viết →
Phát triển phần mềm

Hàm Lambda của Python: Cú pháp, cách sử dụng thực tế và khi nào không nên sử dụng chúng

Các hàm lambda của Python được giải thích bằng mã chúng tôi đã chạy: cú pháp, sắp xếp bằng khóa, bản đồ và bộ lọc, các phần đóng, bẫy liên kết muộn …

Đọc bài viết →
Trí tuệ nhân tạo

Đại lý AI là gì? Cách chúng hoạt động, với vòng lặp tác nhân đơn giản, bạn có thể chạy

Tác nhân AI là gì? Hướng dẫn đơn giản về vòng lặp tác nhân, công cụ, bộ nhớ và lan can, với một vòng lặp Python nhỏ mà chúng tôi đã chạy, những rủi …

Đọc bài viết →
DevOps

Giám sát và Khả năng quan sát: Sự khác biệt thực sự, với nhật ký, số liệu và dấu vết

Giải thích về giám sát và khả năng quan sát: lỗi đã biết và chưa biết, nhật ký, số liệu và dấu vết, hướng dẫn về sự cố thanh toán, tín hiệu vàng, Op…

Đọc bài viết →
DevOps

Docker Volumes vs Bind Mounts: Duy trì dữ liệu vùng chứa đúng cách

Giải thích về khối lượng Docker và liên kết gắn kết: tại sao dữ liệu vùng chứa biến mất, khối lượng được đặt tên, liên kết gắn kết, tmpfs, ví dụ về …

Đọc bài viết →
Tự động hóa kiểm thử

TDD vs BDD: Key Differences, One Feature Built Both Ways and When to Use Each

TDD và BDD được giải thích bằng một tính năng giảm giá được xây dựng theo cả hai cách: tái cấu trúc màu đỏ-xanh với mã chúng tôi đã chạy, kịch bản C…

Đọc bài viết →
Kiểm thử phần mềm

Kiểm tra chấp nhận của người dùng (UAT): Quy trình, danh sách kiểm tra và ví dụ thực tế

Giải thích về thử nghiệm chấp nhận của người dùng: ai chạy nó, nó khác với QA như thế nào, quy trình bảy bước, mẫu trường hợp thử nghiệm UAT, danh s…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về các giá trị NULL của SQL: IS NULL, COALESCE, NULLIF và những cái bẫy cần tránh

Các giá trị SQL NULL được giải thích bằng các truy vấn chúng tôi đã chạy: logic ba giá trị, IS NULL, COALESCE, NULLIF, cách tổng hợp, kết hợp và sắp…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Câu lệnh SQL CASE WHEN: Cú pháp, ví dụ thực tế và các lỗi thường gặp

TRƯỜNG HỢP SQL KHI được giải thích bằng các truy vấn mà chúng tôi đã chạy: các biểu mẫu đơn giản và được tìm kiếm, thứ tự điều kiện, các thủ thuật S…

Đọc bài viết →
Phát triển phần mềm

JWT là gì? Mã thông báo Web JSON được giải thích bằng một ví dụ hoạt động

JWT là gì? Mã thông báo Web JSON đã giải thích: ba phần, mã thông báo được xây dựng và giả mạo trong mã chúng tôi đã chạy, JWT so với phiên, lưu trữ…

Đọc bài viết →
Phát triển phần mềm

Giải thích về vòng lặp sự kiện JavaScript: Ngăn xếp cuộc gọi, Microtask và bộ hẹn giờ kèm ví dụ

Vòng lặp sự kiện JavaScript được giải thích bằng mã chúng tôi đã chạy: ngăn xếp cuộc gọi, hàng đợi tác vụ và vi nhiệm, tại sao setTimeout 0 không di…

Đọc bài viết →
Phát triển phần mềm

Giải thích về trình tạo và năng suất của Python: Tiết kiệm bộ nhớ bằng các ví dụ thực tế

Trình tạo và lợi nhuận Python được giải thích bằng mã chúng tôi đã chạy: cách chúng tạm dừng và tiếp tục, đo mức tiết kiệm bộ nhớ, quy trình, chuỗi …

Đọc bài viết →
Trí tuệ nhân tạo

Nhúng là gì? Giải thích sự tương đồng về vectơ và Cosine một cách đơn giản

nhúng là gì? Hướng dẫn bằng ngôn ngữ đơn giản về vectơ, độ tương tự cosine và tìm kiếm ngữ nghĩa, với một ví dụ nhỏ mà chúng tôi đã chạy, các cách s…

Đọc bài viết →
DevOps

Triển khai Blue-Green và Canary: Sự khác biệt, sự đánh đổi và cách lựa chọn

Giải thích về triển khai Blue-green và Canary: cách hoạt động của từng loại, chi phí, rủi ro và khôi phục, nhóm người dùng ổn định mà chúng tôi đã t…

Đọc bài viết →
Tự động hóa kiểm thử

Kiểm tra không ổn định: Nguyên nhân gây ra chúng và cách khắc phục chúng vĩnh viễn

Các thử nghiệm không ổn định được giải thích bằng các bản demo mà chúng tôi đã chạy: nguyên nhân chính, cách xác nhận và chẩn đoán nguyên nhân, cách…

Đọc bài viết →
Kiểm thử phần mềm

Kiểm tra tải và kiểm tra căng thẳng: Sự khác biệt, số liệu và ví dụ về k6

Giải thích về thử nghiệm tải và thử nghiệm căng thẳng: mỗi thử nghiệm chứng minh điều gì, thử nghiệm tăng đột biến và ngâm, số liệu quan trọng, lý d…

Đọc bài viết →
Kiểm thử phần mềm

Trường hợp thử nghiệm và kịch bản thử nghiệm: Sự khác biệt chính, ví dụ và thời điểm sử dụng từng trường hợp

Giải thích trường hợp kiểm thử và kịch bản kiểm thử: định nghĩa rõ ràng, bảng cạnh nhau, một tính năng đặt lại mật khẩu được lấy từ các tình huống n…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Tối ưu hóa truy vấn SQL: Đọc kế hoạch thực thi và sửa các truy vấn chậm, có tính thời gian

Đã thử nghiệm tối ưu hóa truy vấn SQL trên một triệu hàng: đọc kế hoạch thực hiện, thêm chỉ mục phù hợp, sửa các bộ lọc không thể mở rộng, sử dụng c…

Đọc bài viết →
Cơ sở dữ liệu & SQL

SQL UNION và UNION ALL: Sự khác biệt, ví dụ và hiệu suất đã được kiểm tra

SQL UNION và UNION ALL được giải thích bằng các truy vấn chúng tôi đã chạy: trùng lặp, cả hai quy tắc đều tuân theo, lỗi dữ liệu thực, hiệu suất đượ…

Đọc bài viết →
Phát triển phần mềm

Hướng dẫn API tìm nạp JavaScript: GET, POST, Xử lý lỗi và hết thời gian chờ

Hướng dẫn API tìm nạp JavaScript đã được thử nghiệm trên máy chủ cục bộ: GET và POST, tại sao 404 không gửi, trình trợ giúp có thể sử dụng lại, chuỗ…

Đọc bài viết →
Phát triển phần mềm

Xử lý tệp Python: Đọc, ghi, CSV, JSON và pathlib kèm ví dụ

Việc xử lý tệp Python được giải thích bằng mã chúng tôi đã chạy: chế độ mở, với, đọc tệp lớn, CSV, JSON, pathlib, tệp nhị phân, ghi an toàn, xử lý l…

Đọc bài viết →
Phát triển phần mềm

Các lớp và đối tượng Python: Hướng dẫn OOP với các ví dụ thực tế

Các lớp và đối tượng Python được giải thích bằng mã mà chúng tôi đã chạy: __init__, các phương thức, thuộc tính lớp và phiên bản, tính kế thừa, thuộ…

Đọc bài viết →
Trí tuệ nhân tạo

Mô hình ngôn ngữ lớn là gì? LLM hoạt động như thế nào, được giải thích mà không cường điệu hóa

Mô hình ngôn ngữ lớn là gì? LLM được giải thích bằng ngôn ngữ đơn giản: mã thông báo, phần nhúng, sự chú ý, đào tạo, cửa sổ nhiệt độ và ngữ cảnh, mộ…

Đọc bài viết →
DevOps

Các lệnh Linux cho người mới bắt đầu: Hướng dẫn thiết bị đầu cuối cần thiết kèm ví dụ

Các lệnh Linux dành cho người mới bắt đầu, được nhóm theo tác vụ: điều hướng, tệp, xem nhật ký, grep, đường dẫn, quyền, quy trình và lưu trữ, cùng v…

Đọc bài viết →
Tự động hóa kiểm thử

Selenium vs Nhà viết kịch: Sự khác biệt chính, So sánh mã và nên chọn cái nào

Selenium và Playwright được so sánh: kiến trúc, chờ đợi, hỗ trợ trình duyệt và ngôn ngữ, gỡ lỗi, kiểm tra giống nhau ở cả hai công cụ, lời khuyên di…

Đọc bài viết →
Kiểm thử phần mềm

Phân vùng tương đương: Giải thích kỹ thuật thiết kế thử nghiệm bằng các ví dụ đã thực hiện

Giải thích về phân vùng tương đương: cách tìm các phân vùng hợp lệ và không hợp lệ, các ví dụ hoạt động theo độ tuổi, mật khẩu và phiếu giảm giá, cá…

Đọc bài viết →
Kiểm thử phần mềm

Mức độ nghiêm trọng và mức độ ưu tiên trong kiểm thử phần mềm: Sự khác biệt, Ma trận và ví dụ thực tế

Giải thích về mức độ nghiêm trọng và mức độ ưu tiên trong kiểm thử phần mềm: định nghĩa rõ ràng, ma trận bốn chiều với các ví dụ, thang đo cấp độ, a…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Hướng dẫn về truy vấn con SQL: Các loại, truy vấn con tương quan và TỒN TẠI kèm ví dụ

Hướng dẫn về truy vấn con SQL với các truy vấn chúng tôi đã chạy: truy vấn con vô hướng, IN, FROM và SELECT, truy vấn con tương quan, EXISTS, bẫy và…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về giao dịch SQL và ACID: Các mức CAM KẾT, ROLLBACK và Cô lập

Các giao dịch SQL và ACID được giải thích bằng chuyển khoản ngân hàng mà chúng tôi đã thực hiện: CAM KẾT, ROLLBACK, điểm lưu trữ, khóa, mức cách ly,…

Đọc bài viết →
Phát triển phần mềm

Git merge vs rebase: khác biệt, ví dụ và khi nào dùng cái nào

Git merge vs rebase được giải thích bằng đầu ra log thực tế, bảng so sánh, quy tắc vàng của rebase và quy trình làm việc nhóm an toàn.

Đọc bài viết →
Phát triển phần mềm

List comprehension trong Python: cú pháp, ví dụ và khi nào nên tránh

List comprehension trong Python: cú pháp, lọc dữ liệu, if-else, vòng lặp lồng nhau, thời gian đo thực tế và khi nào vòng lặp for thông thường tốt hơn.

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích SQL JOIN kèm ví dụ (Inner, Left, Right, Full)

Hiểu SQL JOIN từng bước với bảng và truy vấn mẫu: INNER, LEFT, RIGHT, FULL, CROSS và SELF, cùng lỗi thường gặp và mẹo hiệu năng.

Đọc bài viết →