Ini muncul dari pertanyaan terkait ini , di mana saya ingin tahu bagaimana memaksa dua transaksi terjadi secara berurutan dalam kasus sepele (di mana keduanya beroperasi hanya pada satu baris). Saya mendapat jawaban — gunakan SELECT ... FOR UPDATE
sebagai baris pertama dari kedua transaksi — tetapi ini menimbulkan masalah: Jika transaksi pertama tidak pernah dilakukan atau dibatalkan, maka transaksi kedua akan diblokir tanpa batas waktu. The innodb_lock_wait_timeout
variabel menetapkan jumlah detik setelah klien mencoba untuk membuat transaksi kedua akan diberitahu "Maaf, coba lagi" ... tetapi sejauh yang saya tahu, mereka akan mencoba lagi sampai server reboot berikutnya. Begitu:
- Tentunya harus ada cara untuk memaksa
ROLLBACK
jika transaksi berlangsung selamanya? Haruskah saya menggunakan daemon untuk membunuh transaksi seperti itu, dan jika demikian, seperti apa daemon itu? - Jika koneksi terputus oleh
wait_timeout
atauinteractive_timeout
pertengahan transaksi, apakah transaksi dibatalkan? Apakah ada cara untuk menguji ini dari konsol?
Klarifikasi : innodb_lock_wait_timeout
menetapkan jumlah detik bahwa suatu transaksi akan menunggu kunci dirilis sebelum menyerah; apa yang saya inginkan adalah cara memaksa kunci untuk dilepaskan.
Pembaruan 1 : Berikut adalah contoh sederhana yang menunjukkan mengapa innodb_lock_wait_timeout
tidak cukup untuk memastikan bahwa transaksi kedua tidak diblokir oleh yang pertama:
START TRANSACTION;
SELECT SLEEP(55);
COMMIT;
Dengan pengaturan default innodb_lock_wait_timeout = 50
, transaksi ini selesai tanpa kesalahan setelah 55 detik. Dan jika Anda menambahkan UPDATE
sebelum SLEEP
baris, kemudian memulai transaksi kedua dari klien lain yang mencoba ke SELECT ... FOR UPDATE
baris yang sama, itu adalah transaksi kedua yang habis, bukan yang tertidur.
Apa yang saya cari adalah cara untuk memaksa tidur nyenyak dari transaksi ini.
Pembaruan 2 : Menanggapi kekhawatiran hobodave tentang seberapa realistis contoh di atas, berikut ini skenario alternatif: DBA terhubung ke server langsung dan berjalan
START TRANSACTION
SELECT ... FOR UPDATE
di mana baris kedua mengunci baris yang sering ditulis aplikasi. Kemudian DBA terganggu dan berjalan pergi, lupa untuk mengakhiri transaksi. Aplikasi terhenti hingga baris tidak terkunci. Saya ingin meminimalkan waktu aplikasi macet karena kesalahan ini.
ROLLBACK
transaksi pertama jika perlu lebih dari n
detik untuk menyelesaikannya. Apakah ada cara untuk melakukannya?
MYSQL
memiliki konfigurasi untuk mencegah skenario ini. Karena tidak dapat diterima server hang karena klien tidak bertanggung jawab. Saya tidak menemukan kesulitan untuk memahami pertanyaan Anda juga sangat relevan.