2013-04-23 30 views
69

Tôi đã đọc về 4 mức độ cách ly:giao dịch liên quan mức độ cách ly với ổ khóa trên bàn

Isolation Level  Dirty Read Nonrepeatable Read Phantom Read 
READ UNCOMMITTED  Permitted  Permitted   Permitted 
READ COMMITTED    --  Permitted   Permitted 
REPEATABLE READ    --    --    Permitted 
SERIALIZABLE    --    --    -- 

Tôi muốn hiểu khóa mỗi cô lập giao dịch mất trên bảng

READ UNCOMMITTED - no lock on table 
READ COMMITTED - lock on committed data 
REPEATABLE READ - lock on block of sql(which is selected by using select query) 
SERIALIZABLE - lock on full table(on which Select query is fired) 

dưới đây là ba hiện tượng có thể xảy ra trong cách ly giao dịch
Đọc bẩn - không khóa
Nonrepeatable đọc - không đọc bẩn như khóa trên dữ liệu cam kết
Phantom đọc - khóa trên khối sql (được lựa chọn bằng cách sử dụng chọn truy vấn)

Tôi muốn hiểu nơi chúng tôi xác định các mức cách ly này: chỉ ở cấp jdbc/hibernate hoặc trong DB cũng

PS: Tôi đã xem qua các liên kết trong Isolation levels in oracle, nhưng có vẻ vụng về và nói chuyện trên cơ sở dữ liệu cụ thể

+3

Điều này hoàn toàn phụ thuộc vào cơ sở dữ liệu. Cơ sở dữ liệu khác nhau có thể sử dụng các thuật toán khác nhau cho các mức cô lập. Một số có thể sử dụng MVCC (không có khóa trên truy vấn chọn), một số sử dụng khóa 2 pha nghiêm ngặt (khóa chia sẻ và độc quyền). –

Trả lời

109

Tôi muốn hiểu khóa mỗi cô lập giao dịch mất trên bảng

Ví dụ, bạn có 3 quá trình đồng thời A, B và C. Một bắt đầu một giao dịch, ghi dữ liệu và cam/rollback (tùy thuộc vào kết quả). B chỉ thực thi câu lệnh SELECT để đọc dữ liệu. C đọc và cập nhật dữ liệu. Tất cả các quy trình này đều hoạt động trên cùng một bảng T.

  • ĐỌC KHÔNG ĐƯỢC ĐẢM BẢO - không khóa trên bàn. Bạn có thể đọc dữ liệu trong bảng trong khi viết trên đó. Điều này có nghĩa, A ghi dữ liệu (không phổ biến) và B có thể đọc dữ liệu không được kiểm soát này và sử dụng nó (cho bất kỳ mục đích nào). Nếu A thực hiện một rollback, B vẫn đọc dữ liệu và sử dụng nó. Đây là cách nhanh nhất nhưng không an toàn nhất để làm việc với dữ liệu vì có thể dẫn đến các lỗ dữ liệu trong các bảng không liên quan đến thể chất (có, hai bảng có thể logic nhưng không liên quan đến vật lý trong các ứng dụng thế giới thực = \).
  • ĐỌC KẾT NỐI - khóa dữ liệu đã cam kết. Bạn có thể đọc dữ liệu chỉ được cam kết. Điều này có nghĩa, A ghi dữ liệu và B không thể đọc dữ liệu được lưu bởi A cho đến khi A thực hiện một cam kết. Vấn đề ở đây là C có thể cập nhật dữ liệu đã được đọc và sử dụng trên máy khách B và B sẽ không có dữ liệu cập nhật.
  • READEATABLE READ - lock trên khối sql (được chọn bằng cách sử dụng truy vấn chọn). Điều này có nghĩa, B đọc dữ liệu dưới một số điều kiện tức là WHERE aField > 10 AND aField < 20, Dữ liệu chèn trong đó giá trị aField nằm trong khoảng từ 10 đến 20, sau đó B đọc lại dữ liệu và nhận kết quả khác.
  • SERIALIZABLE - khóa trên bàn đầy đủ (trên đó Chọn truy vấn được kích hoạt). Điều này có nghĩa, B đọc dữ liệu và không có giao dịch nào khác có thể sửa đổi dữ liệu trên bảng. Đây là cách an toàn nhất nhưng chậm nhất để làm việc với dữ liệu. Ngoài ra, do hoạt động đọc đơn giản khóa bảng, điều này có thể dẫn đến các vấn đề nặng về sản xuất: hãy tưởng tượng rằng bảng T là bảng Hóa đơn, người dùng X muốn biết hóa đơn trong ngày và người dùng Y muốn tạo hóa đơn mới , do đó, trong khi X thực hiện đọc các hóa đơn, Y không thể thêm một hóa đơn mới (và khi nó về tiền, mọi người trở nên thực sự điên, đặc biệt là các ông chủ).

Tôi muốn hiểu nơi mà chúng tôi xác định các mức cách ly: chỉ jdbc/hibernate mức hoặc trong DB cũng

Sử dụng JDBC, bạn xác định nó bằng cách sử Connection#setTransactionIsolation.

Sử dụng Hibernate:

<property name="hibernate.connection.isolation">2</property> 

đâu

  • 1: ĐỌC không bị giam
  • 2: ĐỌC CAM KẾT
  • 4: REPEATABLE READ
  • 8: SERIALIZABLE

Cấu hình Hibernate được lấy từ here (xin lỗi, bằng tiếng Tây Ban Nha).

Bằng cách này, bạn có thể thiết lập mức độ cô lập trên RDBMS cũng như:

và bật và bật ...

+0

https://docs.oracle.com/cd/B12037_01/server.101/b10743/consist.htm Chỉ cần thêm cho Oracle: Người ta có thể thiết lập mức cô lập của một giao dịch bằng cách sử dụng một trong các câu lệnh này ở đầu giao dịch: THIẾT LẬP TIẾP CẬN GIAO DỊCH GIAO TIẾP ĐỌC; THIẾT LẬP TIẾP CẬN GIAO DIỆN ĐỘC QUYỀN; ĐẶT CHUYỂN GIAO CHỈ; –

+2

Ngoài ra, để tiết kiệm chi phí mạng và xử lý của mỗi giao dịch bằng câu lệnh SET TRANSACTION, bạn có thể sử dụng câu lệnh ALTER SESSION để thiết lập mức cô lập giao dịch cho tất cả các giao dịch tiếp theo: ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE; ALTER SESSION SET ISOLATION_LEVEL ĐỌC KẾT NỐI; –

+0

Tôi muốn đề cập đến, vấn đề chính của READ COMMITED đề cập đến việc không trả về dữ liệu cũ trên lựa chọn, nhưng cho các cuộc đua cập nhật đồng thời, khi chuỗi C không thể cam kết vì A đã thay đổi dữ liệu ở giữa giao dịch của C. Điều đó cần điều trị đặc biệt về mức thiết kế, đối diện với SERIALIZABLE, nơi giao dịch không thể chồng lên nhau. –

4

Ổ khóa luôn được lấy ở mức DB: -

Tài liệu chính thức của Oracle: - Để tránh xung đột trong giao dịch, DBMS sử dụng khóa, cơ chế chặn truy cập bởi người khác vào dữ liệu đang được truy cập bởi giao dịch. (Lưu ý rằng trong chế độ tự động cam kết, trong đó mỗi câu lệnh là một giao dịch, các khóa được giữ cho chỉ một câu lệnh.) Sau khi khóa được thiết lập, nó vẫn có hiệu lực cho đến khi giao dịch được thực hiện hoặc quay lại. Ví dụ, một DBMS có thể khóa một hàng của một bảng cho đến khi các bản cập nhật cho nó đã được cam kết. Hiệu quả của khóa này sẽ là để ngăn chặn người dùng nhận được một đọc bẩn, đó là, đọc một giá trị trước khi nó được thực hiện vĩnh viễn. (Truy cập vào một giá trị cập nhật chưa được cam kết được coi là đọc dơ bẩn vì có thể giá trị đó được cuộn ngược về giá trị trước đó của nó. Nếu bạn đọc một giá trị sau đó được cuộn lại, bạn sẽ đọc một giá trị không hợp lệ.)

Cách khóa được đặt được xác định bởi mức được gọi là mức cách ly giao dịch, có thể dao động từ việc không hỗ trợ giao dịch đến các giao dịch hỗ trợ thực thi các quy tắc truy cập rất nghiêm ngặt.

Một ví dụ về mức cách ly giao dịch là TRANSACTION_READ_COMMITTED, sẽ không cho phép truy cập giá trị cho đến khi nó được cam kết. Nói cách khác, nếu mức cách ly giao dịch được đặt thành TRANSACTION_READ_COMMITTED, thì DBMS không cho phép đọc dơ bẩn. Giao diện Kết nối bao gồm năm giá trị đại diện cho các mức cô lập giao dịch mà bạn có thể sử dụng trong JDBC.

6

Khi trà brb nói, phụ thuộc vào việc triển khai cơ sở dữ liệu và thuật toán chúng sử dụng: MVCC hoặc Khóa hai pha.

CUBRID (mã nguồn mở RDBMS) explains ý tưởng của hai thuật toán này:

  • Hai pha khóa (2pl)

Người đầu tiên là khi giao dịch T2 cố gắng thay đổi bản ghi A, nó biết rằng giao dịch T1 đã thay đổi bản ghi A và đợi cho đến khi giao dịch T1 hoàn tất vì giao dịch T2 không thể biết liệu giao dịch T1 có giao dịch hay không ion sẽ được cam kết hoặc cuộn trở lại. Phương pháp này được gọi là Khóa hai pha (2PL).

  • Multi-phiên bản kiểm soát đồng thời (MVCC)

Một trong những khác là cho phép mỗi trong số họ, T1 và T2 giao dịch, để có phiên bản thay đổi của mình. Ngay cả khi giao dịch T1 có thay đổi bản ghi A từ 1 đến 2, giao dịch T1 rời khỏi giá trị ban đầu 1 và ghi rằng phiên bản giao dịch T1 của bản ghi A là 2. Sau đó, giao dịch T2 sau thay đổi bản ghi A từ 1 đến 3, không phải từ 2 đến 4 và ghi rằng phiên bản giao dịch T2 của bản ghi A là 3.

Khi giao dịch T1 được cuộn lại, không quan trọng nếu 2, phiên bản giao dịch T1, không áp dụng cho bản ghi A. Sau , nếu giao dịch T2 được cam kết, phiên bản 3, T2 giao dịch sẽ được áp dụng cho bản ghi A. Nếu giao dịch T1 là được cam kết trước giao dịch T2, bản ghi A được thay đổi thành 2, và sau đó đến 3 tại thời điểm thực hiện giao dịch T2. Trạng thái cơ sở dữ liệu cuối cùng giống với trạng thái thực hiện mỗi giao dịch độc lập, không ảnh hưởng đến các giao dịch khác. Do đó, nó thỏa mãn thuộc tính ACID. Phương pháp này được gọi là Điều khiển đồng thời nhiều phiên bản (MVCC).

MVCC cho phép sửa đổi đồng thời với chi phí tăng phí trong bộ nhớ (vì nó phải duy trì các phiên bản khác nhau của cùng dữ liệu) và tính toán (ở mức REPETEABLE_READ bạn không thể cập nhật để kiểm tra phiên bản của dữ liệu, như Hiberate thực hiện với Optimistick Locking).

Trong 2pl Transaction isolation levels control the following:

  • Cho dù ổ khóa được thực hiện khi dữ liệu được đọc, và những loại ổ khóa được yêu cầu.

  • Thời lượng khóa đọc được giữ.

  • Cho dù một hoạt động đọc tham khảo hàng sửa đổi bởi giao dịch khác:

    • Dừng cho đến khi khóa độc quyền trên hàng được giải phóng.

    • Truy lục phiên bản cam kết của hàng đã tồn tại tại thời điểm tuyên bố hoặc giao dịch bắt đầu.

    • Đọc sửa đổi dữ liệu không được cam kết.

Chọn một mức cô lập giao dịch không ảnh hưởng đến ổ khóa mà được mua để bảo vệ dữ liệu thay đổi. Giao dịch luôn nhận được khóa độc quyền trên mọi dữ liệu mà nó sửa đổi và giữ khóa đó cho đến khi giao dịch hoàn tất, bất kể mức cách ly được đặt cho giao dịch đó. Đối với các hoạt động đọc, mức cách ly giao dịch chủ yếu xác định mức độ bảo vệ khỏi các tác động của sửa đổi được thực hiện bởi các giao dịch khác.

Mức cô lập thấp hơn làm tăng khả năng của nhiều người sử dụng để truy cập dữ liệu cùng một lúc, nhưng tăng số lượng đồng thời tác như bẩn lần đọc hoặc bị mất thông tin cập nhật, mà người dùng có thể gặp gỡ.

ví dụ bê tông của mối quan hệ giữa khóa và mức độ cô lập trong SQL Server (sử dụng 2pl trừ trên READ_COMMITED với READ_COMMITTED_SNAPSHOT = ON)

  • READ_UNCOMMITED: không phát hành ổ khóa chia sẻ để ngăn chặn các giao dịch khác và thay đổi dữ liệu đọc bởi giao dịch hiện tại. Các giao dịch READ UNCOMMITTED cũng không bị chặn bởi các khóa độc quyền có thể ngăn giao dịch hiện tại đọc các hàng đã được sửa đổi nhưng không bị các giao dịch khác thực hiện. [...]

  • READ_COMMITED:

    • Nếu READ_COMMITTED_SNAPSHOT được thiết lập để OFF (mặc định): Sử dụng ổ khóa để ngăn chặn các giao dịch khác từ hàng sửa đổi trong khi giao dịch hiện tại đang chạy một hoạt động đọc chia sẻ. Các khóa chia sẻ cũng chặn các tuyên bố từ đọc hàng sửa đổi bởi các giao dịch khác cho đến khi giao dịch khác được hoàn thành. [...] Khóa hàng được phát hành trước khi hàng tiếp theo được xử lý. [...]
    • Nếu READ_COMMITTED_SNAPSHOT được đặt thành BẬT, Công cụ cơ sở dữ liệu sử dụng phiên bản hàng để trình bày từng câu lệnh với ảnh chụp nhanh nhất quán về dữ liệu khi nó tồn tại ở đầu câu lệnh. Khóa không được sử dụng để bảo vệ dữ liệu khỏi các cập nhật của các giao dịch khác.
  • REPETEABLE_READ: Khóa được chia sẻ được đặt trên tất cả dữ liệu được đọc bởi mỗi câu lệnh trong giao dịch và được giữ cho đến khi giao dịch hoàn tất.

  • SERIALIZABLE: Khóa phạm vi được đặt trong phạm vi giá trị khóa phù hợp với điều kiện tìm kiếm của từng câu lệnh được thực thi trong giao dịch. [...] Các khóa phạm vi được giữ cho đến khi giao dịch hoàn tất.

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