Perbedaan antara "baca komitmen" dan "baca berulang"

245

Saya pikir tingkat isolasi di atas sangat mirip. Bisakah seseorang tolong jelaskan dengan beberapa contoh bagus apa perbedaan utamanya?

Depan
sumber
3
Anda harus mengembangkan pertanyaan dan menambahkan tag untuk "level isolasi" apa yang Anda maksud (Java, dll). "level isolasi" adalah istilah yang agak ambigu, dan Anda jelas meminta jawaban untuk lingkungan tertentu.
jesup

Jawaban:

564

Komitmen baca adalah tingkat isolasi yang menjamin bahwa setiap data yang dibaca dilakukan saat ini dibaca. Ini hanya membatasi pembaca dari melihat bacaan perantara, tidak berkomitmen, 'kotor'. Tidak ada janji sama sekali bahwa jika transaksi menerbitkan kembali baca, akan menemukan data yang sama , data bebas untuk diubah setelah dibaca.

Pembacaan berulang adalah tingkat isolasi yang lebih tinggi, bahwa selain jaminan tingkat yang sudah dibaca, juga menjamin bahwa setiap pembacaan data tidak dapat berubah , jika transaksi membaca data yang sama lagi, itu akan menemukan data yang sebelumnya dibaca di tempat, tidak berubah. , dan tersedia untuk dibaca.

Tingkat isolasi berikutnya, serializable, membuat jaminan lebih kuat: selain semua jaminan baca berulang, itu juga menjamin bahwa tidak ada data baru yang dapat dilihat oleh pembacaan berikutnya.

Katakanlah Anda memiliki tabel T dengan kolom C dengan satu baris di dalamnya, katakan memiliki nilai '1'. Dan anggap Anda memiliki tugas sederhana seperti berikut:

BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;

Itu adalah tugas sederhana yang mengeluarkan dua bacaan dari tabel T, dengan penundaan 1 menit di antara mereka.

  • di bawah READ COMMITTED, SELECT kedua dapat mengembalikan data apa pun . Transaksi bersamaan dapat memperbarui catatan, menghapusnya, menyisipkan catatan baru. Pilihan kedua akan selalu melihat data baru .
  • di bawah REPEATABLE READ, SELECT kedua dijamin untuk menampilkan setidaknya baris yang dikembalikan dari SELECT pertama tidak berubah . Baris baru dapat ditambahkan oleh transaksi bersamaan dalam satu menit itu, tetapi baris yang ada tidak dapat dihapus atau diubah.
  • di bawah tulisan SERIALIZABLE, pemilihan kedua dijamin untuk melihat baris yang sama persis dengan yang pertama. Tidak ada baris yang dapat diubah, atau dihapus, atau baris baru dapat dimasukkan oleh transaksi bersamaan.

Jika Anda mengikuti logika di atas, Anda dapat dengan cepat menyadari bahwa transaksi SERIALIZABLE, walaupun dapat membuat hidup Anda lebih mudah, selalu sepenuhnya memblokir setiap operasi bersamaan yang mungkin, karena mereka mengharuskan tidak ada yang dapat memodifikasi, menghapus, atau menyisipkan baris apa pun. Tingkat isolasi transaksi default dari System.Transactionsruang lingkup .Net adalah serializable, dan ini biasanya menjelaskan kinerja luar biasa yang dihasilkan.

Dan akhirnya, ada juga level isolasi SNAPSHOT. Level isolasi SNAPSHOT membuat jaminan yang sama dengan serializable, tetapi tidak dengan mensyaratkan bahwa tidak ada transaksi konkuren yang dapat memodifikasi data. Alih-alih, ia memaksa setiap pembaca untuk melihat versinya sendiri di dunia (ini adalah 'snapshot'). Ini membuatnya sangat mudah untuk diprogram dan juga sangat terukur karena tidak memblokir pembaruan secara bersamaan. Namun, manfaat itu datang dengan harga: konsumsi sumber daya server tambahan.

Tambahan berbunyi:

Remus Rusanu
sumber
24
Saya pikir ada kesalahan di atas untuk REPEATABLE READ: Anda mengatakan baris yang ada tidak dapat dihapus atau diubah, tetapi saya pikir mereka dapat dihapus atau diubah karena membaca berulang hanya membaca "snapshot" bukan data aktual. Dari docs dev.mysql.com/doc/refman/5.0/en/… : "Semua bacaan yang konsisten dalam transaksi yang sama bacalah snapshot yang dibuat oleh bacaan pertama."
Derek Litz
2
@Derek Litz Apakah saya benar bahwa Anda mengatakan: Data DAPAT / MUNGKIN diubah dari pihak ketiga, sementara transaksi sedang berlangsung, tetapi pembacaan masih akan melihat data asli 'lama' seolah-olah perubahan belum diambil tempat (snapshot).
Programster
5
@Batang jagung. Ya, pembacaan Phantom dapat terjadi dari penghapusan (atau penyisipan). Ya, pembacaan hantu dapat terjadi dalam isolasi baca berulang (hanya dari sisipan). Tidak, pembacaan Phantom dari penghapusan tidak dapat terjadi dalam isolasi baca berulang. Menguji. Apa yang saya katakan tidak bertentangan dengan dokumentasi yang Anda kutip.
AndyBrown
4
@Cornstalks NP. Saya hanya menyebutkannya sama sekali karena saya sendiri tidak 100% yakin dan harus menyelam lebih dalam untuk memastikan siapa yang benar! Dan saya tidak ingin pembaca masa depan menyesatkan. Sedang menyimpan komentar, mungkin yang terbaik untuk tetap seperti yang disarankan. Saya yakin orang lain yang tertarik pada tingkat detail halus akan cukup khusus untuk membaca semua komentar !!
AndyBrown
12
Terima kasih karena tidak menghapus komentar Anda. Diskusi membantu menghubungkan lebih banyak titik.
Josh
68

Baca berulang

Keadaan basis data dipertahankan sejak awal transaksi. Jika Anda mengambil nilai di session1, lalu perbarui nilai itu di session2, mengambilnya lagi di session1 akan mengembalikan hasil yang sama. Membaca berulang.

session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Aaron

Baca Berkomitmen

Dalam konteks transaksi, Anda akan selalu mengambil nilai komitmen terbaru. Jika Anda mengambil nilai di session1, perbarui di session2, lalu ambil di session1again, Anda akan mendapatkan nilai seperti yang diubah di session2. Bunyinya baris berkomitmen terakhir.

session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Bob

Masuk akal?

Hazel_arun
sumber
Saya mencoba Baca Berulang di SQL Server 2008 dengan "set tingkat isolasi baca yang dapat diulang". Membuat dua jendela permintaan sql. Tetapi tidak berhasil. Mengapa?
Aditya Bokade
1
Mengapa sesi kedua masih membacakan Aaron? Bukankah transaksi session2 selesai dan dilakukan? Saya tahu ini lama, tapi mungkin seseorang bisa menjelaskan.
Sonny Childs
9
Saya pikir Baca Berulang akan memblokir sesi kedua hingga sesi pertama dilakukan. Jadi contohnya salah.
Nighon
4
Dalam kasus Repeatable Read, ketika sesi 1 membaca baris, itu menempatkan kunci bersama, yang tidak akan mengizinkan kunci Eksklusif (ke sesi 2) untuk pembaruan, karenanya data tidak dapat diperbarui.
Taher
Saya pikir SQL server dan MySQL berperilaku berbeda ketika datang untuk memperbarui baris bersama antara dua transaksi
user2488286
23

Cukup jawaban sesuai dengan bacaan dan pemahaman saya pada utas ini dan jawaban @ remus-rusanu didasarkan pada skenario sederhana ini:

Ada dua proses A dan B. Proses B membaca Tabel X Proses A menulis dalam tabel X Proses B membaca lagi Tabel X.

  • ReadUncommitted : Proses B dapat membaca data yang tidak berkomitmen dari proses A dan bisa melihat baris yang berbeda berdasarkan penulisan B. Tidak ada kunci sama sekali
  • ReadCommitted : Proses B dapat membaca HANYA data yang dikomit dari proses A dan itu bisa melihat baris yang berbeda berdasarkan pada penulisan B yang dikomit. bisakah kita menyebutnya Kunci Sederhana?
  • RepeatableRead : Proses B akan membaca data (baris) yang sama apa pun yang dilakukan Proses A. Tetapi proses A dapat mengubah baris lain. Baris tingkat Blok
  • Serialisable : Proses B akan membaca baris yang sama seperti sebelumnya dan Proses A tidak dapat membaca atau menulis dalam tabel. Blok tingkat tabel
  • Snapshot : setiap proses memiliki salinannya sendiri dan mereka sedang mengerjakannya. Masing-masing memiliki pandangan sendiri
Mo Zaatar
sumber
15

Pertanyaan lama yang sudah memiliki jawaban yang diterima, tapi saya suka memikirkan dua level isolasi ini dalam hal bagaimana mereka mengubah perilaku penguncian dalam SQL Server. Ini mungkin bermanfaat bagi mereka yang men-debug deadlock seperti saya.

BACA BERKOMITMEN (default)

Kunci bersama diambil dalam SELECT dan kemudian dirilis ketika pernyataan SELECT selesai . Ini adalah bagaimana sistem dapat menjamin bahwa tidak ada pembacaan kotor dari data yang tidak dikomit. Transaksi lain masih dapat mengubah baris yang mendasari setelah SELECT Anda selesai dan sebelum transaksi Anda selesai.

BACA ULANG

Kunci bersama diambil dalam SELECT dan kemudian dirilis hanya setelah transaksi selesai . Ini adalah bagaimana sistem dapat menjamin bahwa nilai yang Anda baca tidak akan berubah selama transaksi (karena mereka tetap terkunci sampai transaksi selesai).

Chris Gillum
sumber
13

Mencoba menjelaskan keraguan ini dengan diagram sederhana.

Komitmen Baca: Di sini, di level isolasi ini, Transaksi T1 akan membaca nilai terbaru dari X yang dilakukan oleh Transaksi T2.

Baca Berkomitmen

Baca Berulang: Di tingkat isolasi ini, Transaksi T1 tidak akan mempertimbangkan perubahan yang dilakukan oleh Transaksi T2.

masukkan deskripsi gambar di sini

vkrishna17
sumber
1

Saya pikir gambar ini juga dapat berguna, ini membantu saya sebagai referensi ketika saya ingin cepat mengingat perbedaan antara tingkat isolasi (terima kasih kepada kudvenkat di youtube)

masukkan deskripsi gambar di sini

Ivan Pavičić
sumber
0

Harap dicatat bahwa, yang berulang dalam hal membaca berulang untuk tupel, tetapi tidak untuk seluruh tabel. Dalam tingkat isolasi ANSC, phantom read anomaly dapat terjadi, yang berarti membaca tabel dengan yang sama di mana klausa dua kali dapat mengembalikan hasil yang berbeda. Secara harfiah, itu tidak dapat diulang .

不辞 长 做 岭南 人
sumber
-1

Pengamatan saya pada solusi awal yang diterima.

Di bawah RR (default mysql) - Jika tx terbuka dan SELECT telah dipecat, tx lain TIDAK dapat menghapus baris apa pun yang termasuk hasil BACA sebelumnya yang ditetapkan hingga tx sebelumnya dilakukan (pada kenyataannya pernyataan penghapusan di tx baru hanya akan hang) , namun tx berikutnya dapat menghapus semua baris dari tabel tanpa masalah. Btw, BACA berikutnya di tx sebelumnya masih akan melihat data lama sampai berkomitmen.

Sanjeev Dhiman
sumber
2
Anda mungkin ingin meletakkannya di bagian komentar agar penjawab mendapat pemberitahuan. Dengan begitu dia akan bisa menanggapi pengamatan Anda dan membuat koreksi jika diperlukan.
RBT