2009-05-03 39 views
40

Có vẻ như có những ý kiến ​​rất khác nhau về việc sử dụng các giao dịch để đọc từ cơ sở dữ liệu.Giao dịch cho quyền truy cập DB chỉ đọc?

Trích từ developerWorks Điều Transaction strategies: Models and strategies overview:

Tại sao bạn sẽ cần một giao dịch nếu bạn chỉ đọc dữ liệu? Câu trả lời là bạn không. Bắt đầu từ một giao dịch để thực hiện một read-only hoạt động làm tăng thêm chi phí của thread xử lý và có thể gây ra chia sẻ khóa đọc trên cơ sở dữ liệu (tùy vào loại cơ sở dữ liệu bạn đang sử dụng và những gì mức độ cách ly được thiết lập đến).

Là một quan điểm ngược lại có đoạn trích sau đây từ tài liệu Hibernate Non-transactional data access and the auto-commit mode

khuyến nghị của chúng tôi là không sử dụng chế độ autocommit trong một ứng dụng, và để áp dụng read-only chỉ khi giao dịch có hiệu suất rõ ràng là lợi ích hoặc khi các thay đổi mã trong tương lai rất khó xảy ra. Luôn thích giao dịch ACID thông thường cho nhóm hoạt động truy cập dữ liệu của bạn, bất kể bạn đọc hay ghi dữ liệu.

Cũng có một cuộc tranh luận tương tự trên danh sách gửi thư EclipseLink here.

Vậy sự thật nằm ở đâu? Các giao dịch để đọc thực hành tốt nhất hay không? Nếu cả hai đều là giải pháp khả thi, thì tiêu chí để sử dụng giao dịch là gì?

Theo như tôi thấy, nó chỉ tạo sự khác biệt nếu mức cách ly cao hơn 'đã đọc cam kết'. Điều này có đúng không?

Trải nghiệm và đề xuất là gì?

Trả lời

16

Steven Devijver cung cấp một số lý do chính đáng để bắt đầu giao dịch ngay cả khi hoạt động chỉ sẽ đọc cơ sở dữ liệu:

  • Set timeout hoặc chế độ khóa
  • Set mức cô lập

Chuẩn SQL đòi hỏi rằng ngay cả một truy vấn phải bắt đầu một giao dịch mới nếu không có giao dịch nào đang được tiến hành. Có DBMS nơi đó không phải là những gì xảy ra - những người có chế độ tự động, ví dụ (câu lệnh bắt đầu một giao dịch và cam kết nó ngay lập tức câu lệnh hoàn thành). Các DBMS khác tạo các câu lệnh nguyên tử (có hiệu lực tự động) theo mặc định, nhưng bắt đầu một giao dịch rõ ràng với một câu lệnh như 'BEGIN WORK', hủy tự động cho đến khi COMMIT hoặc ROLLBACK tiếp theo (IBM Informix Dynamic Server là một cơ sở dữ liệu không phải là MODE) ANSI).

Tôi không chắc chắn về lời khuyên không bao giờ được khôi phục. Nó làm cho không có sự khác biệt đối với giao dịch chỉ đọc, và trong phạm vi nó làm phiền các DBA của bạn, thì tốt hơn là tránh ROLLBACK. Nhưng nếu chương trình của bạn thoát mà không thực hiện COMMIT, DBMS sẽ thực hiện ROLLBACK trên giao dịch không đầy đủ của bạn - chắc chắn nếu nó sửa đổi cơ sở dữ liệu và (để đơn giản) ngay cả khi bạn chỉ chọn dữ liệu.

Nhìn chung, nếu bạn muốn thay đổi hành vi mặc định của một loạt các hoạt động, hãy sử dụng giao dịch, ngay cả khi giao dịch là chỉ đọc. Nếu bạn hài lòng với hành vi mặc định, thì việc sử dụng giao dịch không quan trọng. Nếu mã của bạn là để được di chuyển giữa DBMS, tốt nhất là giả sử rằng bạn sẽ cần một giao dịch.

8

Giao dịch được yêu cầu cho các thao tác chỉ đọc nếu bạn muốn đặt thời gian chờ cụ thể cho các truy vấn khác với thời gian chờ mặc định hoặc nếu bạn muốn thay đổi mức cách ly.

Ngoài ra, mọi cơ sở dữ liệu - không biết về ngoại lệ - sẽ bắt đầu giao dịch nội bộ cho mỗi truy vấn. Nó thường được coi là không được thực hiện cho các giao dịch rollback khi rollback đó là không cần thiết.

DBA có thể đang theo dõi hoạt động khôi phục và mọi hành vi rollback mặc định sẽ làm phiền chúng trong trường hợp đó.

Vì vậy, giao dịch vẫn được sử dụng dù bạn có bắt đầu hay không. Nếu bạn không cần chúng, đừng bắt đầu chúng, nhưng đừng bao giờ thực hiện một thao tác khôi phục trên các thao tác chỉ đọc.

8

Trước hết, điều này nghe có vẻ như tối ưu hóa sớm. Như Steven đã chỉ ra, hầu hết các cơ sở dữ liệu sane sẽ đưa bạn vào một giao dịch dù sao, và tất cả những gì họ đang thực sự làm là gọi cam kết sau mỗi tuyên bố. Vì vậy, từ quan điểm đó, tự động có thể ít hiệu suất hơn vì mỗi câu lệnh phải bắt đầu một giao dịch mới. Hoặc có thể không. Chỉ điểm chuẩn sẽ cho biết và tôi đặt cược nó không làm cho một lick của sự khác biệt để ứng dụng của bạn.

Một lý do tại sao bạn muốn luôn sử dụng giao dịch là tính nhất quán về bảo vệ. Nếu bạn bắt đầu nghịch bằng cách khai báo một giao dịch theo cách thủ công chỉ khi bạn "cần" thì bạn sẽ quên vào một thời điểm quan trọng. Hoặc đó được cho là chỉ đọc tập hoạt động đột nhiên không phải là, hoặc bởi vì một lập trình viên sau này đã không nhận ra nó được cho là hoặc vì mã của bạn gọi một hàm có một ghi ẩn. Ví dụ, tôi cấu hình các máy khách cơ sở dữ liệu dòng lệnh của tôi để không tự động. Điều này có nghĩa là tôi có thể xóa ngón tay một truy vấn xóa và vẫn khôi phục.

Có mức cách ly, như được chỉ ra. Điều này cho phép bạn thực hiện nhiều lần đọc mà không phải lo lắng nếu một số quy trình khác đã ghi vào dữ liệu của bạn ở giữa chúng khiến cho lượt đọc của bạn có hiệu quả nguyên tử. Điều này sẽ giúp bạn tiết kiệm từ một giờ gỡ lỗi một điều kiện chủng tộc.

Và cuối cùng, bạn thường có thể đặt giao dịch thành chỉ đọc. Điều này kiểm tra giả định của bạn và sẽ lỗi nếu có điều gì đó cố gắng viết.

Here's a nice article summing it all up. Chi tiết cụ thể về Oracle, nhưng các khái niệm là chung chung.

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