Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Kapan menggunakan SELECT ... FOR UPDATE?

Satu-satunya cara portabel untuk mencapai konsistensi antara ruang dan tag dan memastikan ruang tidak pernah dikembalikan setelah dihapus adalah menguncinya dengan SELECT FOR UPDATE .

Namun dalam beberapa sistem penguncian adalah efek samping dari kontrol konkurensi, dan Anda mencapai hasil yang sama tanpa menentukan FOR UPDATE secara eksplisit.

Untuk mengatasi masalah ini, Thread 1 harus SELECT id FROM rooms FOR UPDATE , sehingga mencegah Thread 2 menghapus dari rooms sampai Thread 1 selesai. Apakah itu benar?

Ini tergantung pada kontrol konkurensi yang digunakan sistem database Anda.

  • MyISAM di MySQL (dan beberapa sistem lama lainnya) mengunci seluruh tabel selama kueri.

  • Di SQL Server , SELECT kueri menempatkan kunci bersama pada catatan / halaman / tabel yang telah mereka periksa, sementara DML kueri menempatkan kunci pembaruan (yang kemudian dipromosikan menjadi eksklusif atau diturunkan ke kunci bersama). Kunci eksklusif tidak kompatibel dengan kunci bersama, jadi SELECT atau DELETE kueri akan terkunci hingga sesi lain dilakukan.

  • Dalam database yang menggunakan MVCC (seperti Oracle , PostgreSQL , MySQL dengan InnoDB ), sebuah DML query membuat salinan catatan (dalam satu atau lain cara) dan umumnya pembaca tidak memblokir penulis dan sebaliknya. Untuk database ini, SELECT FOR UPDATE akan berguna:itu akan mengunci SELECT atau DELETE kueri hingga sesi lain dilakukan, seperti SQL Server tidak.

Kapan seseorang harus menggunakan REPEATABLE_READ isolasi transaksi versus READ_COMMITTED dengan SELECT ... FOR UPDATE ?

Secara umum, REPEATABLE READ tidak melarang baris phantom (baris yang muncul atau hilang dalam transaksi lain, bukan diubah)

  • Di Oracle dan PostgreSQL sebelumnya versi, REPEATABLE READ sebenarnya adalah sinonim untuk SERIALIZABLE . Pada dasarnya, ini berarti bahwa transaksi tidak melihat perubahan yang dilakukan setelah dimulai. Jadi dalam pengaturan ini, Thread 1 terakhir kueri akan mengembalikan ruangan seolah-olah tidak pernah dihapus (yang mungkin atau mungkin bukan yang Anda inginkan). Jika Anda tidak ingin menampilkan ruangan setelah dihapus, Anda harus mengunci baris dengan SELECT FOR UPDATE

  • Di InnoDB , REPEATABLE READ dan SERIALIZABLE adalah hal yang berbeda:pembaca di SERIALIZABLE mode mengatur kunci tombol berikutnya pada catatan yang mereka evaluasi, secara efektif mencegah DML . bersamaan pada mereka. Jadi, Anda tidak memerlukan SELECT FOR UPDATE dalam mode serial, tetapi membutuhkannya dalam REPEATABLE READ atau READ COMMITED .

Perhatikan bahwa standar pada mode isolasi memang menetapkan bahwa Anda tidak melihat keanehan tertentu dalam kueri Anda tetapi tidak menentukan caranya (dengan penguncian atau dengan MVCC atau sebaliknya).

Ketika saya mengatakan "Anda tidak perlu SELECT FOR UPDATE " Saya benar-benar harus menambahkan "karena efek samping dari implementasi mesin basis data tertentu".



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana mendefinisikan pesanan ORDER BY khusus di mySQL

  2. Menggunakan Penasihat Pencadangan Basis Data untuk Mengotomatiskan Tugas Pemeliharaan

  3. Menggunakan Oracle JDeveloper Snippets dengan MySQL

  4. PDO::__construct():Server mengirim charset (255) yang tidak diketahui klien. Tolong, laporkan ke pengembang

  5. Pisahkan nilai dari satu bidang menjadi dua