Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Khi nào sử dụng SELECT ... FOR UPDATE?

Cách di động duy nhất để đạt được sự nhất quán giữa các phòng và thẻ và đảm bảo rằng các phòng không bao giờ được trả lại sau khi chúng đã bị xóa là khóa chúng bằng SELECT FOR UPDATE .

Tuy nhiên, trong một số hệ thống, khóa là một tác dụng phụ của điều khiển đồng thời và bạn đạt được kết quả tương tự mà không cần chỉ định FOR UPDATE một cách rõ ràng.

Để giải quyết vấn đề này, Chuỗi 1 nên SELECT id FROM rooms FOR UPDATE , do đó ngăn Luồng 2 xóa khỏi rooms cho đến khi Chủ đề 1 được thực hiện. Có đúng không?

Điều này phụ thuộc vào điều khiển đồng thời mà hệ thống cơ sở dữ liệu của bạn đang sử dụng.

  • MyISAM trong MySQL (và một số hệ thống cũ khác) không khóa toàn bộ bảng trong thời gian truy vấn.

  • Trong SQL Server , SELECT các truy vấn đặt các ổ khóa được chia sẻ trên các bản ghi / trang / bảng mà chúng đã kiểm tra, trong khi DML truy vấn đặt các khóa cập nhật (sau này được thăng cấp thành khóa độc quyền hoặc giảm cấp xuống khóa dùng chung). Các khóa dành riêng không tương thích với các khóa dùng chung, vì vậy SELECT hoặc DELETE truy vấn sẽ khóa cho đến khi một phiên khác thực hiện.

  • Trong cơ sở dữ liệu sử dụng MVCC (như Oracle , PostgreSQL , MySQL với InnoDB ), một DML truy vấn tạo ra một bản sao của bản ghi (theo cách này hay cách khác) và nói chung người đọc không chặn người viết và ngược lại. Đối với các cơ sở dữ liệu này, SELECT FOR UPDATE sẽ hữu ích:nó sẽ khóa SELECT hoặc DELETE truy vấn cho đến khi một phiên khác cam kết, giống như SQL Server không.

Khi nào thì nên sử dụng REPEATABLE_READ cách ly giao dịch so với READ_COMMITTED với SELECT ... FOR UPDATE ?

Nói chung, REPEATABLE READ không cấm các hàng ảo (các hàng đã xuất hiện hoặc biến mất trong một giao dịch khác, thay vì được sửa đổi)

  • Trong OraclePostgreSQL cũ hơn phiên bản, REPEATABLE READ thực sự là một từ đồng nghĩa với SERIALIZABLE . Về cơ bản, điều này có nghĩa là giao dịch không thấy các thay đổi được thực hiện sau khi nó đã bắt đầu. Vì vậy, trong thiết lập này, Thread 1 cuối cùng truy vấn sẽ trả về căn phòng như thể nó chưa bao giờ bị xóa (có thể có hoặc không như những gì bạn muốn). Nếu bạn không muốn hiển thị các phòng sau khi chúng đã bị xóa, bạn nên khóa các hàng bằng SELECT FOR UPDATE

  • Trong InnoDB , REPEATABLE READSERIALIZABLE là những thứ khác nhau:người đọc trong SERIALIZABLE chế độ đặt khóa phím tiếp theo trên các bản ghi mà chúng đánh giá, ngăn chặn hiệu quả DML đồng thời về họ. Vì vậy, bạn không cần SELECT FOR UPDATE ở chế độ có thể tuần tự hóa, nhưng cần chúng trong REPEATABLE READ hoặc READ COMMITED .

Lưu ý rằng tiêu chuẩn về các chế độ cách ly quy định rằng bạn không thấy một số câu hỏi nhất định trong các truy vấn của mình nhưng không xác định cách thức (với khóa hoặc với MVCC hoặc cách khác).

Khi tôi nói "bạn không cần SELECT FOR UPDATE "Tôi thực sự nên thêm" vì tác dụng phụ của việc triển khai công cụ cơ sở dữ liệu nhất định ".



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Không thể tạo mô hình dữ liệu thực thể - sử dụng MySql và EF6

  2. SQL Lựa chọn từ hai Bảng có nối bên trong và giới hạn

  3. Kết nối Metabase với MySQL để khám phá dữ liệu

  4. 1114 (HY000):Bảng đã đầy

  5. Sử dụng hàm password_hash và password_verify của PHP 5.5