2010-10-18 29 views
18

Khi làm việc với các giao dịch cơ sở dữ liệu, các điều kiện có thể (nếu có) có thể gây ra tuyên bố cuối cùng COMMIT trong giao dịch là gì, giả sử tất cả các câu lệnh trong giao dịch đã được thực thi mà không có vấn đề?Câu lệnh COMMIT (trong SQL) có bao giờ thất bại không? Làm sao?


... Ví dụ giả sử bạn có một số two-phase hoặc three-phase commit protocol nơi bạn làm một loạt các báo cáo, sau đó chờ cho một số quá trình tổng thể để cho bạn biết khi nó là ok để cuối cùng cam kết giao dịch:

-- <initial handshaking stuff> 
START TRANSACTION; 
-- <Execute a bunch of SQL statements> 
-- <Inform master of readiness to commit> 
-- <Time passes... background transactions happening while we wait> 
-- <Receive approval to commit from master (finally!)> 
COMMIT; 

Nếu mã của bạn nhận được câu lệnh COMMIT cuối cùng và gửi nó đến DBMS của bạn, bạn có bao giờ gặp lỗi (vấn đề duy nhất, cơ sở dữ liệu đầy đủ, v.v.) tại câu lệnh đó không? Lỗi gì? Tại sao? Chúng xuất hiện như thế nào? Nó có thay đổi tùy thuộc vào DBMS bạn chạy không?

+0

Nếu đây là bài tập về nhà, hãy gắn thẻ như vậy. –

+3

@Bob Jarvis: Wow. Cảm ơn vì đã khiến tôi cảm thấy trẻ hơn rất nhiều! – Russ

+4

Bài tập về nhà không phải là chức năng của tuổi tác. :-) –

Trả lời

9

Có thể một số công cụ cơ sở dữ liệu hoãn kiểm tra ràng buộc chỉ mục UNIQUE cho đến khi COMMIT. Rõ ràng nếu ràng buộc không giữ đúng tại thời điểm commit thì nó sẽ thất bại.

+0

Thật sao? Đây là điều tôi sợ. Bạn có biết bất kỳ động cơ cụ thể nào làm điều này không? – Russ

+3

Đây là một tính năng mới trong PostgreSQL 9.0. http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UNIQUE_CONSTRAINTS –

+2

Oracle có thể trì hoãn việc kiểm tra ràng buộc FK, http://infolab.stanford.edu/~ullman/fcdb/oracle/or-triggers.html –

4

Chắc chắn.

Trong môi trường nhiều người dùng, COMMIT có thể không thành công do thay đổi của người dùng khác (ví dụ: COMMIT của bạn sẽ vi phạm ràng buộc tham chiếu khi áp dụng cho cơ sở dữ liệu hiện tại ...).

Thomas

4

Chắc chắn, có thể có một số vấn đề. Hành động cam kết, trong và của chính nó, phải thực hiện một số mục cuối cùng, vĩnh viễn để chỉ ra rằng giao dịch đã cam kết. Nếu làm cho mục đó thất bại, thì giao dịch không thể thực hiện được.

Như Ignacio nói, có thể có kiểm tra ràng buộc hoãn lại (đây có thể là bất kỳ hình thức ràng buộc nào, không chỉ là ràng buộc duy nhất, tùy thuộc vào công cụ DBMS).

Máy chủ SQL Cụ thể: có thể trì hoãn dữ liệu FILESTREAM cho đến thời gian cam kết. Điều đó có thể thất bại.

4

Một mục rất đơn giản và thường bị bỏ qua: lỗi phần cứng. Cam kết có thể thất bại nếu máy chủ cơ bản chết. Đây có thể là đĩa, cpu, bộ nhớ hoặc thậm chí là mạng có liên quan.

Giao dịch có thể thất bại nếu giao dịch không bao giờ nhận được sự chấp thuận từ chính (vì bất kỳ lý do nào).

15

COMMIT có thể không thành công. Bạn có thể đã có các nguồn lực đủ để ghi lại tất cả các thay đổi mà bạn muốn thực hiện, nhưng thiếu tài nguyên để thực sự thực hiện các thay đổi.

Và đó là không xem xét lý do khác, nó có thể thất bại:

  1. Sự thay đổi bản thân có thể không phù hợp với những hạn chế của cơ sở dữ liệu.

  2. Mất điện dừng mọi thứ hoàn tất.

  3. Mức độ đồng thời lựa chọn được yêu cầu có thể không cho phép cập nhật (ví dụ: con trỏ cập nhật bảng đã sửa đổi).

  4. Cam kết có thể hết thời gian hoặc kết nối vào thời gian do sự cố đói.

  5. Kết nối mạng giữa máy khách và cơ sở dữ liệu có thể bị mất.

Và tất cả các lý do "đơn giản" khác không nằm trên đỉnh đầu của tôi.

1

Không có vấn đề làm thế nào tuyệt vời một hệ thống có thể được thiết kế, sẽ có một số khả năng rằng một cam kết sẽ nhận được vào một tình huống mà nó không thể biết liệu nó đã thành công hay không. Trong một số trường hợp, điều đó có thể không quan trọng (ví dụ: nếu ổ đĩa cứng giữ cơ sở dữ liệu biến thành một đống xỉ, có thể không thể biết liệu cam kết đã thành công hay chưa trước khi xảy ra nhưng nó sẽ không thực sự quan trọng); trong những trường hợp khác, tuy nhiên, điều này có thể là một vấn đề. Đặc biệt với các hệ thống cơ sở dữ liệu phân tán, nếu một lỗi kết nối xảy ra vào đúng thời điểm trong một lần commit, nó sẽ có thể cho cả hai bên xác định liệu phía bên kia có mong đợi một cam kết hay một rollback hay không.

4

Nếu bạn đang sử dụng cam kết hai pha thì không. Tất cả mọi thứ có thể đi sai được thực hiện trong giai đoạn chuẩn bị.

Vẫn có thể bị mất mạng, ít điện năng hơn, tia vũ trụ, v.v., nhưng ngay cả như vậy, các giao dịch sẽ được ghi vào bộ nhớ vĩnh viễn và nếu một cam kết được kích hoạt, quy trình khôi phục sẽ mang chúng xuyên qua.

Hy vọng.

Các vấn đề liên quan