Apa perbedaan antara pembacaan yang tidak dapat diulang dan pembacaan hantu?
Saya telah membaca artikel Isolasi (sistem basis data) dari Wikipedia , tetapi saya punya beberapa keraguan. Dalam contoh di bawah ini, apa yang akan terjadi: baca yang tidak dapat diulang dan baca hantu ?
Transaksi ASELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
KELUARAN:
1----MIKE------29019892---------5000
Transaksi B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Transaksi A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Keraguan lain adalah, pada contoh di atas, level isolasi mana yang harus digunakan? Dan mengapa?
database
oracle
transactions
isolation-level
transaction-isolation
pengguna1357722
sumber
sumber
Jawaban:
Dari Wikipedia (yang memiliki contoh bagus dan terperinci untuk ini):
dan
Contoh sederhana:
select sum(x) from table;
akan mengembalikan hasil yang berbeda walaupun tidak ada baris yang terpengaruh sendiri yang diperbarui, jika baris telah ditambahkan atau dihapus.Level isolasi apa yang Anda butuhkan tergantung pada aplikasi Anda. Ada biaya tinggi ke tingkat isolasi "lebih baik" (seperti pengurangan konkurensi).
Dalam contoh Anda, Anda tidak akan membaca hantu, karena Anda hanya memilih dari satu baris (diidentifikasi dengan kunci utama). Anda dapat memiliki bacaan yang tidak dapat diulang, jadi jika itu merupakan masalah, Anda mungkin ingin memiliki tingkat isolasi yang mencegahnya. Di Oracle, transaksi A juga bisa mengeluarkan SELECT FOR UPDATE, maka transaksi B tidak dapat mengubah baris sampai A selesai.
sumber
Cara sederhana yang saya suka pikirkan adalah:
Pembacaan non-berulang dan phantom berkaitan dengan operasi modifikasi data dari transaksi yang berbeda, yang dilakukan setelah transaksi Anda dimulai, dan kemudian dibaca oleh transaksi Anda.
Pembacaan yang tidak dapat diulang adalah ketika transaksi Anda membaca UPDATES yang dilakukan dari transaksi lain. Baris yang sama sekarang memiliki nilai yang berbeda dengan ketika transaksi Anda dimulai.
Pembacaan hantu serupa tetapi ketika membaca dari SERI dan / atau HAPUS dari transaksi lain yang dilakukan. Ada baris atau baris baru yang telah menghilang sejak Anda memulai transaksi.
Pembacaan yang kotor mirip dengan pembacaan yang tidak dapat diulang dan phantom, tetapi berhubungan dengan membaca data yang TIDAK DIKOMPITASI, dan terjadi ketika PEMBARUAN, INSERT, atau HAPUS dari transaksi lain dibaca, dan transaksi lainnya belum melakukan data. Itu sedang membaca data "sedang berlangsung", yang mungkin tidak lengkap, dan mungkin tidak pernah benar-benar dilakukan.
sumber
Seperti yang dijelaskan dalam artikel ini , anomali Baca Tidak Berulang terlihat sebagai berikut:
Dalam artikel ini tentang Phantom Read , Anda dapat melihat bahwa anomali ini dapat terjadi sebagai berikut:
Jadi, sementara Non-Repeatable Read berlaku untuk satu baris, Phantom Read adalah tentang serangkaian catatan yang memenuhi kriteria pemfilteran kueri yang diberikan.
sumber
Baca fenomena
UPDATE
kueri dari transaksi lainINSERT
atauDELETE
permintaan dari transaksi lainCatatan : HAPUS pernyataan dari transaksi lain, juga memiliki probabilitas yang sangat rendah untuk menyebabkan pembacaan yang tidak dapat diulang dalam kasus tertentu. Sayangnya, hal ini terjadi ketika pernyataan DELETE menghapus baris yang sama dengan yang ditanyakan oleh transaksi Anda saat ini. Tetapi ini adalah kasus yang jarang, dan jauh lebih tidak mungkin terjadi dalam database yang memiliki jutaan baris di setiap tabel. Tabel yang berisi data transaksi biasanya memiliki volume data tinggi di lingkungan produksi apa pun.
Kami juga dapat mengamati bahwa UPDATES mungkin merupakan pekerjaan yang lebih sering dalam kebanyakan kasus penggunaan daripada INSERT atau DELETES yang sebenarnya (dalam kasus seperti itu, bahaya pembacaan yang tidak dapat diulang hanya tinggal - pembacaan hantu tidak mungkin dalam kasus tersebut). Inilah sebabnya mengapa UPDAT diperlakukan berbeda dari INSERT-DELETE dan anomali yang dihasilkan juga dinamai berbeda.
Ada juga biaya pemrosesan tambahan yang terkait dengan penanganan untuk INSERT-DELETEs, daripada hanya menangani UPDATES.
Manfaat tingkat isolasi yang berbeda
Lalu mengapa tidak mengatur transaksi SERIALIZABLE setiap saat? Nah, jawaban untuk pertanyaan di atas adalah: Pengaturan SERIALIZABLE membuat transaksi sangat lambat , yang lagi-lagi tidak kita inginkan.
Bahkan konsumsi waktu transaksi dalam tingkat berikut:
Jadi pengaturan READ_UNCOMMITTED adalah yang tercepat .
Ringkasan
Sebenarnya kita perlu menganalisis use case dan memutuskan tingkat isolasi sehingga kita mengoptimalkan waktu transaksi dan juga mencegah sebagian besar anomali.
Perhatikan bahwa database secara default memiliki pengaturan REPEATABLE_READ.
sumber
Ada perbedaan dalam implementasi antara kedua jenis tingkat isolasi ini.
Untuk "non-repeatable read", penguncian baris diperlukan.
Untuk "phantom read", penguncian ruang lingkup diperlukan, bahkan penguncian meja.
Kita dapat mengimplementasikan dua level ini dengan menggunakan protokol penguncian dua fase .
sumber
Dalam sistem dengan bacaan yang tidak dapat diulang, hasil dari permintaan kedua Transaksi A akan mencerminkan pembaruan dalam Transaksi B - ia akan melihat jumlah yang baru.
Dalam sistem yang memungkinkan phantom membaca, jika Transaksi B menyisipkan baris baru dengan ID = 1, Transaksi A akan melihat baris baru ketika kueri kedua dijalankan; yaitu pembacaan hantu adalah kasus khusus pembacaan yang tidak dapat diulang.
sumber
Jawaban yang diterima menunjukkan sebagian besar dari semua yang disebut perbedaan antara keduanya sebenarnya tidak signifikan sama sekali.
Jika "satu baris diambil dua kali dan nilai-nilai di dalam baris berbeda antara pembacaan", maka itu bukan baris yang sama (bukan tuple yang sama dalam pembicaraan RDB yang benar) dan itu memang berdasarkan definisi juga halnya bahwa "koleksi baris yang dikembalikan oleh kueri kedua berbeda dari yang pertama ".
Mengenai pertanyaan "tingkat isolasi mana yang harus digunakan", semakin banyak data Anda yang sangat penting bagi seseorang, di suatu tempat, semakin besar kemungkinan Serializable adalah satu-satunya pilihan yang masuk akal.
sumber
Saya pikir ada beberapa perbedaan antara Non-repeateable-read & phantom-read.
Non-berulang berarti ada transaksi derek A & B. jika B dapat melihat modifikasi A, jadi mungkin terjadi membaca kotor, jadi kami membiarkan B memperhatikan modifikasi A setelah A melakukan.
Ada masalah baru: kita membiarkan B memperhatikan modifikasi A setelah A melakukan, itu berarti A memodifikasi nilai baris yang dipegang B, kadang-kadang B akan membaca baris lagi, sehingga B akan mendapatkan nilai baru yang berbeda dengan pertama kali kita dapatkan, kami menyebutnya Non-berulang, untuk menangani masalah ini, kami membiarkan B mengingat sesuatu (karena saya belum tahu apa yang akan diingat) ketika B mulai.
Mari kita pikirkan solusi baru, kita dapat melihat ada masalah baru juga, karena kita membiarkan B mengingat sesuatu, jadi apa pun yang terjadi dalam A, B tidak dapat terpengaruh, tetapi jika B ingin memasukkan beberapa data ke dalam tabel dan B periksa tabel untuk memastikan tidak ada catatan, tetapi data ini telah dimasukkan oleh A, jadi mungkin terjadi beberapa kesalahan. Kami menyebutnya Phantom-read.
sumber
non-repeatable read adalah level isolasi dan phantom read (membaca nilai yang dikomit oleh transaksi lain) adalah sebuah konsep (tipe pembacaan misalnya pembacaan kotor atau pembacaan snapshot). Tingkat isolasi baca yang tidak dapat diulang memungkinkan membaca hantu tetapi tidak membaca kotor atau membaca snapshot.
sumber