Bạn nói đúng: theo tiêu chuẩn isolation level, read committed
, bạn không cần phải quấn các câu lệnh chọn trong giao dịch. Chọn câu lệnh sẽ được bảo vệ khỏi đọc bẩn nếu bạn quấn chúng trong một giao dịch hay không.
connection 1: connection 2:
begin transaction
update user set name = 'Bill' where id = 1
select name from users where id = 1
rollback transaction
Câu lệnh chọn sẽ không đọc bản cập nhật được cuộn lại: không quan trọng là chúng không được gói trong giao dịch.
Nếu bạn cần repeatable reads, sau đó gói chọn trong một giao dịch mặc định không giúp:
connection 1: connection 2:
begin transaction
select name from users where id = 1
update user set name = 'Bill' where id = 1
select name from users where id = 1
commit transaction
Các begin
và commit
tuyên bố sẽ không giúp đỡ ở đây: thứ hai select
thể đọc tên cũ, hoặc số có thể đọc tên mới.
Tuy nhiên, nếu bạn chạy ở mức độ cô lập cao hơn, như serializable
hoặc repeatable read
, nhóm sẽ được bảo vệ khỏi không lặp lại lần đọc:
connection 1: connection 2:
set transaction isolation level
repeatable read
begin transaction
select name from users where id = 1
update user set name = 'Bill' where id = 1
select name from users where id = 1 |
commit transaction |
|--> executed here
Trong kịch bản này, các update
sẽ chặn cho đến khi giao dịch đầu tiên hoàn tất.
Mức cô lập cao hơn hiếm khi được sử dụng vì chúng làm giảm số lượng người có thể làm việc trong cơ sở dữ liệu cùng một lúc. Ở cấp cao nhất, serializable
, truy vấn báo cáo sẽ tạm dừng mọi hoạt động cập nhật.
Về đoạn cuối cùng của bạn, ** Tại sao khối cập nhật? ** Không thể cập nhật sẽ vẫn đi qua mà không chặn, nhưng giao dịch đầu tiên được đọc lặp lại, vẫn sẽ tiếp tục làm việc với các giá trị cũ ? – Pacerier
@Pacerier: Đọc lặp lại nói rằng nếu bạn đọc hai lần, lần đọc thứ hai sẽ trả về cùng một kết quả. Không giống như Oracle hoặc PostgeSQL, SQL Server không giữ các giá trị cũ xung quanh. Bạn có thể thay đổi hành vi này bằng ['SET READ_COMMITTED_SNAPSHOT ON'] (http://msdn.microsoft.com/en-us/library/ms345124.aspx). – Andomar
Hmm, đây là kỳ quặc, có vẻ là mặc định trên MySQL. Vì vậy, đối với máy chủ sql, sau khi chạy 'set read_committed_snapshot on', có quyền nói rằng" cập nhật "sẽ ** không còn ** chặn không? – Pacerier