2008-10-13 25 views
20

Khung ứng dụng nội bộ mà chúng tôi sử dụng tại công ty của tôi làm cho mọi truy vấn SQL thành các giao dịch, mặc dù nếu tôi biết rằng không có lệnh nào sẽ thực hiện thay đổi trong cơ sở dữ liệu. Vào cuối phiên, trước khi đóng kết nối, tôi cam kết giao dịch đóng nó đúng cách. Tôi tự hỏi nếu có bất kỳ sự khác biệt cụ thể nếu tôi cuộn nó trở lại, đặc biệt là về tốc độ.Có sự khác biệt giữa cam kết và rollback trong một giao dịch chỉ có lựa chọn không?

Xin lưu ý rằng tôi đang sử dụng Oracle, nhưng tôi đoán các cơ sở dữ liệu khác có hành vi tương tự. Ngoài ra, tôi không thể làm bất cứ điều gì về yêu cầu để bắt đầu giao dịch, một phần của codebase nằm ngoài tay tôi.

Trả lời

12

Cơ sở dữ liệu thường lưu giữ một tạp chí trước hình ảnh (trước khi giao dịch) hoặc một tạp chí sau hình ảnh (nó sẽ diễn ra khi giao dịch hoàn thành.) Nếu nó giữ hình ảnh trước đó, phải được khôi phục trên một rollback. Nếu nó giữ một hình ảnh sau, điều đó phải thay thế dữ liệu trong trường hợp một cam kết.

Oracle có cả không gian tạp chí và cuộn lùi. Nhật ký giao dịch tích lũy các khối mà sau này được viết bởi các nhà văn DB. Vì chúng không đồng bộ, hầu như không có gì nhà văn DB liên quan có bất kỳ tác động nào đến giao dịch của bạn (nếu hàng đợi đầy, thì bạn có thể phải đợi.)

Ngay cả đối với giao dịch chỉ truy vấn, tôi sẵn sàng đặt cược có một chút lưu giữ hồ sơ giao dịch trong các lĩnh vực rollback của Oracle. Tôi nghi ngờ rằng một rollback đòi hỏi một số công việc trên một phần của Oracle trước khi nó xác định không có gì để thực sự quay trở lại. Và tôi nghĩ rằng điều này là đồng bộ với giao dịch của bạn. Bạn không thể thực sự giải phóng bất kỳ khóa nào cho đến khi hoàn thành quá trình quay lại. [Vâng, tôi biết bạn không sử dụng bất kỳ giao dịch nào, nhưng vấn đề về khóa là lý do tại sao tôi cho rằng việc khôi phục hoàn toàn được phát hành sau đó tất cả các khóa có thể được phát hành, sau đó hoàn tất khôi phục của bạn.]

Bật Mặt khác, cam kết là nhiều hơn hoặc ít hơn kết quả mong đợi, và tôi nghi ngờ rằng loại bỏ các khu vực rollback có thể nhanh hơn một chút. Bạn không tạo mục giao dịch nào, do đó, người viết db sẽ không bao giờ thức dậy để kiểm tra và khám phá ra rằng không có gì để làm.

Tôi cũng hy vọng rằng trong khi cam kết có thể nhanh hơn, sự khác biệt sẽ không đáng kể. Quá nhỏ, bạn thậm chí không thể đo lường chúng khi so sánh song song.

+5

Tôi không nhận ra điều này như một mô tả về cách thức hoạt động của oracle. Nó giống như một mô tả chung đã được áp dụng cho Oracle. Đoán làm thế nào Oracle hoạt động không có khả năng để được helful. –

+0

Oracle gọi nhật ký là "Tệp nhật ký làm lại". Nó gọi các phân đoạn rollback là "Undo Tablespace". Bạn có biết cái nào nhanh hơn không? Cam kết hoặc quay lại? –

+0

Nếu không có việc phải làm thì hầu như chắc chắn không có sự khác biệt. Oracle được tối ưu hóa để cam kết nhanh - nó chỉ yêu cầu bản ghi cam kết được ghi vào bộ đệm đăng nhập làm lại và bộ đệm được xóa (trừ cam kết không đồng bộ trong 10g +). Một rollback là nhiều công việc. –

0

Vì bạn chưa thực hiện bất kỳ DML nào, tôi nghi ngờ sẽ không có sự khác biệt giữa COMMIT và ROLLBACK trong Oracle. Dù bằng cách nào cũng không có gì để làm.

4

Nói chung một COMMIT nhanh hơn nhiều so với ROLLBACK, nhưng trong trường hợp bạn không làm gì thì chúng cũng giống nhau.

8

Tôi đồng ý với các câu trả lời trước rằng không có sự khác biệt giữa COMMIT và ROLLBACK trong trường hợp này. Có thể có một sự khác biệt không đáng kể trong thời gian CPU cần thiết để xác định rằng không có gì để COMMIT so với thời gian CPU cần thiết để xác định rằng không có gì để ROLLBACK. Nhưng, nếu đó là một sự khác biệt không đáng kể, chúng ta có thể quên một cách an toàn về nó. Tuy nhiên, đáng lưu ý là có sự khác biệt giữa phiên làm một loạt các truy vấn trong ngữ cảnh của một giao dịch và một phiên thực hiện cùng các truy vấn trong ngữ cảnh của một loạt các giao dịch.

Nếu khách hàng bắt đầu giao dịch, thực hiện truy vấn, thực hiện COMMITOR ROLLBACK, sau đó bắt đầu giao dịch thứ hai và thực hiện truy vấn thứ hai, không đảm bảo rằng truy vấn thứ hai sẽ quan sát cùng một trạng thái cơ sở dữ liệu như truy vấn đầu tiên. Đôi khi, việc duy trì một chế độ xem nhất quán của dữ liệu là cốt lõi. Đôi khi, việc xem dữ liệu hiện tại càng quan trọng. Nó phụ thuộc vào những gì bạn đang làm.

Tôi biết, tôi biết, OP không hỏi câu hỏi này. Nhưng một số độc giả có thể hỏi nó ở phía sau tâm trí của họ.

3

Các tài liệu nói rằng:

  • Oracle khuyên bạn nên dứt khoát chấm dứt mọi giao dịch trong các chương trình ứng dụng của bạn với một COMMIT hoặc ROLLBACK tuyên bố, trong đó có giao dịch cuối cùng, trước khi ngắt kết nối từ cơ sở dữ liệu Oracle. Nếu bạn không cam kết rõ ràng giao dịch và chương trình chấm dứt bất thường, thì giao dịch không được cam kết cuối cùng sẽ tự động được khôi phục. Một lối thoát bình thường từ hầu hết các tiện ích và công cụ của Oracle làm cho giao dịch hiện tại được thực hiện. Một lối thoát bình thường từ một chương trình biên dịch trước của Oracle không cam kết giao dịch và dựa vào cơ sở dữ liệu Oracle để quay trở lại giao dịch hiện tại.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

Nếu bạn muốn o chọn để làm cái này hay cái khác thì bạn cũng có thể làm một trong đó là giống như không làm gì cả, và chỉ cần cam kết đó.

+0

Nó phụ thuộc vào khách hàng thực sự. sqlplus, một cam kết ngầm định của nó. những người khác nó có thể không được. Nếu kết nối mạng bị cắt đứt (ví dụ: máy khách chỉ "biến mất"), thì đó là một lần khôi phục. –

+0

Tôi không chắc chắn rằng nó không phụ thuộc vào ứng dụng, tôi có lẽ nên nói một "ngắt kết nối duyên dáng", nhưng các tài liệu nói rằng "Một yêu cầu tiềm ẩn xảy ra sau khi chấm dứt bình thường của một ứng dụng hoặc ..." http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/transact.htm # CNCPT1119 –

+0

Thực ra, tôi đã tìm thấy một tài liệu tham khảo tốt hơn và đã chỉnh sửa bài đăng của tôi. Cảm ơn. –

1

Vâng, chúng ta phải tính đến những gì một SELECT trả về trong Oracle. Có hai chế độ. Theo mặc định, một SELECT trả về dữ liệu khi dữ liệu đó nhìn vào đúng lúc câu lệnh SELECT bắt đầu thực thi (đây là hành vi mặc định trong chế độ cách ly READ COMMITTED, chế độ giao dịch mặc định). Vì vậy, nếu một UPDATE/INSERT được thực hiện sau khi SELECT đã được ban hành mà sẽ không được hiển thị trong tập kết quả.

Điều này có thể là một vấn đề nếu bạn cần so sánh hai tập hợp kết quả (ví dụ: debta và các bên tín dụng của một ứng dụng sổ cái chung). Cho rằng chúng ta có một chế độ thứ hai. Trong chế độ đó, SELECT trả về dữ liệu khi nó xem xét thời điểm giao dịch hiện tại bắt đầu (hành vi mặc định trong các mức cô lập READ ONLY và SERIALIZABLE).

Vì vậy, ít nhất đôi khi cần thực hiện các lệnh SELECT trong giao dịch.

0

Tôi nghĩ rằng Cam kết sẽ hiệu quả hơn; vì bạn thường mong đợi hầu hết các giao dịch DB được cam kết; vì vậy bạn sẽ nghĩ rằng DB tối ưu hóa cho trường hợp này (trái ngược với cố gắng để có hiệu quả hơn cho một rollback).

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