Hubungan tingkat isolasi transaksi dengan kunci di atas meja

105

Saya telah membaca tentang 4 tingkat isolasi:

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

Saya ingin memahami kunci yang dimiliki setiap isolasi transaksi di atas meja

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)

di bawah ini adalah tiga fenomena yang dapat terjadi dalam isolasi transaksi
Dirty Read - no lock
Nonrepeatable Read - tidak ada pembacaan kotor sebagai penguncian data yang dilakukan
Phantom Read - mengunci blok sql (yang dipilih dengan menggunakan kueri pemilihan)

Saya ingin memahami di mana kita mendefinisikan tingkat isolasi ini: hanya di tingkat jdbc / hibernate atau di DB juga

PS: Saya telah melalui tautan di tingkat Isolasi di oracle , tetapi mereka terlihat canggung dan berbicara tentang basis data tertentu

Pelajar
sumber
3
Ini sepenuhnya tergantung pada database. Database yang berbeda dapat menggunakan algoritme yang berbeda untuk tingkat isolasi. Beberapa mungkin menggunakan MVCC (tanpa kunci pada kueri tertentu), beberapa menggunakan penguncian 2 fase yang ketat (kunci bersama dan eksklusif).
teh brb

Jawaban:

157

Saya ingin memahami kunci yang dimiliki setiap isolasi transaksi di atas meja

Misalnya, Anda memiliki 3 proses bersamaan A, B, dan C. A memulai transaksi, menulis data, dan melakukan / rollback (bergantung pada hasil). B hanya menjalankan SELECTpernyataan untuk membaca data. C membaca dan memperbarui data. Semua proses ini bekerja pada tabel T. yang sama.

  • BACA TANPA DIKOMITKAN - tidak ada kunci di atas meja. Anda dapat membaca data di tabel sambil menulis di atasnya. Ini berarti A menulis data (tidak terikat) dan B dapat membaca data yang tidak terikat ini dan menggunakannya (untuk tujuan apa pun). Jika A menjalankan rollback, B masih membaca data dan menggunakannya. Ini adalah cara tercepat tetapi paling tidak aman untuk bekerja dengan data karena dapat menyebabkan lubang data di tabel yang tidak terkait secara fisik (ya, dua tabel dapat secara logis tetapi tidak terkait secara fisik di aplikasi dunia nyata = \).
  • BACA BERKOMITMEN - mengunci data yang berkomitmen. Anda dapat membaca data yang hanya dilakukan. Ini berarti A menulis data dan B tidak dapat membaca data yang disimpan oleh A hingga A menjalankan komit. Masalahnya di sini adalah bahwa C dapat memperbarui data yang telah dibaca dan digunakan pada klien B dan B tidak akan memiliki data yang diperbarui.
  • READ REPEATABLE - mengunci blok SQL (yang dipilih dengan menggunakan query select). Artinya B membaca data dalam beberapa kondisi yaitu WHERE aField > 10 AND aField < 20A memasukkan data yang aFieldnilainya antara 10 dan 20, kemudian B membaca kembali data tersebut dan mendapatkan hasil yang berbeda.
  • SERIALIZABLE - mengunci tabel penuh (tempat kueri Select diaktifkan). Artinya, B membaca data dan tidak ada transaksi lain yang dapat mengubah data di tabel. Ini adalah cara paling aman tetapi paling lambat untuk bekerja dengan data. Selain itu, karena operasi baca sederhana mengunci tabel , ini dapat menyebabkan masalah berat pada produksi: bayangkan tabel T adalah tabel Faktur, pengguna X ingin mengetahui faktur hari ini dan pengguna Y ingin membuat faktur baru, jadi sementara X mengeksekusi pembacaan faktur, Y tidak dapat menambahkan faktur baru (dan jika menyangkut uang, orang menjadi sangat marah, terutama para bos).

Saya ingin memahami di mana kita mendefinisikan tingkat isolasi ini: hanya di tingkat JDBC / hibernasi atau di DB juga

Menggunakan JDBC, Anda mendefinisikannya menggunakan Connection#setTransactionIsolation .

Menggunakan Hibernate:

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

Dimana

  • 1: BACA TANPA DIKOMITKAN
  • 2: BACA BERKOMITMEN
  • 4: BACA BERULANG
  • 8: SERIALISASI

Konfigurasi hibernate diambil dari sini (maaf, ini dalam bahasa Spanyol).

Ngomong-ngomong, Anda juga dapat menyetel level isolasi di RDBMS:

dan seterusnya ...

Luiggi Mendoza
sumber
docs.oracle.com/cd/B12037_01/server.101/b10743/consist.htm Hanya untuk menambahkan untuk Oracle: Seseorang dapat mengatur tingkat isolasi transaksi dengan menggunakan salah satu pernyataan berikut di awal transaksi: SET TRANSACTION ISOLATION TINGKAT BACA BERKOMITMEN; TETAPKAN TINGKAT ISOLASI TRANSAKSI SERIALISASI; ATUR TRANSAKSI BACA SAJA;
Pelajar
2
Selain itu, untuk menghemat biaya jaringan dan pemrosesan untuk memulai setiap transaksi dengan pernyataan SET TRANSACTION, Anda dapat menggunakan pernyataan ALTER SESSION untuk mengatur tingkat isolasi transaksi untuk semua transaksi berikutnya: ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE; ALTER SESI SET ISOLATION_LEVEL BACA KOMITTASI;
Pelajar
12
Mengenai BACA BERULANG - Saya pikir contoh yang lebih baik untuk menunjukkannya adalah sebagai berikut: B memulai transaksi, membaca data di blok sql WHERE aField> 10 AND aField <20, data itu dikunci sampai transaksi berakhir. A mencoba memperbarui data itu tetapi menunggu karena kuncinya. Sekarang ketika B akan membaca data itu lagi dalam transaksi yang sama itu dijamin untuk membaca data yang sama, karena terkunci. Koreksi saya jika saya salah.
BornToCode
1
@LuiggiMendoza Sebagai konsep umum, level isolasi hanya tentang Baca Kotor , Baca Tidak Berulang, dan Baris Bayangan . Kunci (S2PL) atau MVCC adalah implementasi untuk vendor yang berbeda.
teh brb
4
@LuiggiMendoza - Saya tidak akurat, seharusnya seperti ini - data yang dibaca B tidak berubah, tetapi pemilihan konsekuen yang dilakukan oleh B dapat mengembalikan lebih banyak baris. Itu karena A tidak dapat mengubah baris yang sudah dibaca B , hingga A melepaskannya. Namun A dapat memasukkan baris baru yang memenuhi syarat kondisi where (dan oleh karena itu saat A akan mengeksekusi pemilihan, ia akan mendapatkan hasil yang berbeda dengan lebih banyak baris - pembacaan bayangan).
BornToCode
9

Seperti yang dikatakan brb tea, tergantung pada implementasi database dan algoritma yang mereka gunakan: MVCC atau Two Phase Locking.

CUBRID (RDBMS open source) menjelaskan ide dari dua algoritma ini:

  • Penguncian dua fase (2PL)

Yang pertama adalah ketika transaksi T2 mencoba untuk mengubah record A, ia mengetahui bahwa transaksi T1 telah mengubah record A dan menunggu sampai transaksi T1 selesai karena transaksi T2 tidak dapat mengetahui apakah transaksi T1 akan dilakukan atau digulung. kembali. Metode ini disebut penguncian dua fase (2PL).

  • Kontrol konkurensi multi-versi (MVCC)

Yang lainnya adalah mengizinkan masing-masing transaksi, T1 dan T2, untuk memiliki versi yang diubah sendiri. Bahkan ketika transaksi T1 telah mengubah catatan A dari 1 ke 2, transaksi T1 meninggalkan nilai asli 1 apa adanya dan menulis bahwa versi transaksi T1 dari catatan A adalah 2. Kemudian, transaksi T2 berikut mengubah catatan A. dari 1 ke 3, bukan dari 2 ke 4, dan menulis bahwa versi transaksi T2 dari rekam A adalah 3.

Saat transaksi T1 dibatalkan, tidak masalah jika 2, versi transaksi T1, tidak diterapkan ke catatan A. Setelah itu, jika transaksi T2 dilakukan, 3, versi transaksi T2, akan diterapkan ke record A. Jika transaksi T1 dilakukan sebelum transaksi T2, catatan A diubah menjadi 2, dan kemudian ke 3 pada saat melakukan transaksi T2. Status database akhir identik dengan status mengeksekusi setiap transaksi secara independen, tanpa berdampak pada transaksi lainnya. Oleh karena itu, ini memenuhi properti ACID. Metode ini disebut kontrol konkurensi multi-versi (MVCC).

MVCC memungkinkan modifikasi serentak dengan biaya overhead yang meningkat dalam memori (karena harus mempertahankan versi berbeda dari data yang sama) dan komputasi (di tingkat REPETEABLE_READ Anda tidak dapat kehilangan pembaruan sehingga harus memeriksa versi datanya, seperti Hiberate lakukan dengan Optimistick Locking ).

Dalam level isolasi Transaksi 2PL mengontrol hal-hal berikut :

  • Apakah kunci diambil saat data dibaca, dan jenis kunci apa yang diminta.

  • Berapa lama kunci baca ditahan.

  • Apakah operasi baca yang mereferensikan baris diubah oleh transaksi lain:

    • Blokir hingga kunci eksklusif di baris tersebut dibebaskan.

    • Ambil versi yang dikomit dari baris yang ada pada saat pernyataan atau transaksi dimulai.

    • Baca modifikasi data tidak terikat.

Memilih tingkat isolasi transaksi tidak mempengaruhi kunci yang diperoleh untuk melindungi modifikasi data. Transaksi selalu mendapatkan kunci eksklusif pada data apa pun yang diubah dan ditahannya kunci tersebut hingga transaksi selesai, terlepas dari tingkat isolasi yang disetel untuk transaksi itu. Untuk operasi baca, tingkat isolasi transaksi terutama menentukan tingkat perlindungan dari efek modifikasi yang dilakukan oleh transaksi lain.

Tingkat isolasi yang lebih rendah meningkatkan kemampuan banyak pengguna untuk mengakses data pada saat yang sama, tetapi meningkatkan jumlah efek konkurensi , seperti pembacaan kotor atau pembaruan yang hilang, yang mungkin ditemui pengguna.

Contoh konkret dari hubungan antara kunci dan tingkat isolasi di SQL Server (gunakan 2PL kecuali pada READ_COMMITED dengan READ_COMMITTED_SNAPSHOT = ON)

  • READ_UNCOMMITED: jangan mengeluarkan kunci bersama untuk mencegah transaksi lain mengubah data yang dibaca oleh transaksi saat ini. BACA transaksi yang TIDAK DIKONTRAK juga tidak diblokir oleh kunci eksklusif yang akan mencegah transaksi saat ini dari membaca baris yang telah dimodifikasi tetapi tidak dilakukan oleh transaksi lain. [...]

  • READ_COMMITED:

    • Jika READ_COMMITTED_SNAPSHOT disetel ke OFF (default): menggunakan kunci bersama untuk mencegah transaksi lain mengubah baris saat transaksi saat ini menjalankan operasi baca. Kunci bersama juga memblokir pernyataan dari membaca baris yang diubah oleh transaksi lain sampai transaksi lain selesai. [...] Kunci baris dilepaskan sebelum baris berikutnya diproses. [...]
    • Jika READ_COMMITTED_SNAPSHOT diatur ke ON, Database Engine menggunakan versi baris untuk menyajikan setiap pernyataan dengan snapshot data yang konsisten secara transaksional seperti yang ada di awal pernyataan. Kunci tidak digunakan untuk melindungi data dari pembaruan oleh transaksi lain.
  • REPETEABLE_READ: Kunci bersama ditempatkan pada semua data yang dibaca oleh setiap pernyataan dalam transaksi dan ditahan sampai transaksi selesai.

  • SERIALIZABLE: Kunci rentang ditempatkan di kisaran nilai kunci yang cocok dengan kondisi pencarian dari setiap pernyataan yang dieksekusi dalam transaksi. [...] Kunci jangkauan ditahan sampai transaksi selesai.

gabrielgiussi
sumber
5

Kunci selalu diambil pada level DB: -

Dokumen Resmi Oracle: - Untuk menghindari konflik selama transaksi, DBMS menggunakan kunci, mekanisme untuk memblokir akses oleh orang lain ke data yang sedang diakses oleh transaksi. (Perhatikan bahwa dalam mode komit otomatis, di mana setiap pernyataan adalah transaksi, kunci hanya ditahan untuk satu pernyataan.) Setelah kunci disetel, kunci tetap berlaku sampai transaksi dilakukan atau dibatalkan. Misalnya, DBMS dapat mengunci baris tabel sampai update telah dilakukan. Efek dari kunci ini adalah untuk mencegah pengguna mendapatkan pembacaan yang kotor, yaitu, membaca nilai sebelum dijadikan permanen. (Mengakses nilai yang diperbarui yang belum dilakukan dianggap sebagai bacaan kotor karena nilai tersebut dapat digulung kembali ke nilai sebelumnya. Jika Anda membaca nilai yang kemudian dibatalkan, Anda akan membaca nilai yang tidak valid. )

Bagaimana kunci ditetapkan ditentukan oleh apa yang disebut tingkat isolasi transaksi, yang dapat berkisar dari tidak mendukung transaksi sama sekali hingga mendukung transaksi yang memberlakukan aturan akses yang sangat ketat.

Salah satu contoh tingkat isolasi transaksi adalah TRANSACTION_READ_COMMITTED, yang tidak akan mengizinkan nilai untuk diakses sampai setelah itu dilakukan. Dengan kata lain, jika tingkat isolasi transaksi disetel ke TRANSACTION_READ_COMMITTED, DBMS tidak mengizinkan pembacaan kotor terjadi. Sambungan antarmuka mencakup lima nilai yang mewakili tingkat isolasi transaksi yang dapat Anda gunakan di JDBC.

Goyal Vicky
sumber