Salah satu trik mudah yang dapat membantu sebagian besar kebuntuan adalah mengurutkan operasi dalam urutan tertentu.
Anda mendapatkan kebuntuan ketika dua transaksi mencoba mengunci dua kunci pada pesanan yang berlawanan, yaitu:
- koneksi 1:kunci kunci(1), kunci kunci(2);
- koneksi 2:kunci kunci(2), kunci kunci(1);
Jika keduanya berjalan pada saat yang sama, koneksi 1 akan mengunci kunci (1), koneksi 2 akan mengunci kunci (2) dan setiap koneksi akan menunggu yang lain untuk melepaskan kunci -> kebuntuan.
Sekarang, jika Anda mengubah kueri Anda sedemikian rupa sehingga koneksi akan mengunci kunci pada urutan yang sama, yaitu:
- koneksi 1:kunci kunci(1), kunci kunci(2);
- koneksi 2:kunci kunci(1 ), kunci kunci(2 );
tidak mungkin menemui jalan buntu.
Jadi ini yang saya sarankan:
-
Pastikan Anda tidak memiliki kueri lain yang mengunci akses lebih dari satu kunci sekaligus kecuali untuk pernyataan hapus. jika Anda melakukannya (dan saya menduga Anda melakukannya), urutkan WHERE mereka di (k1,k2,..kn) dalam urutan menaik.
-
Perbaiki pernyataan penghapusan Anda agar berfungsi dalam urutan menaik:
Ubah
DELETE FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
Untuk
DELETE FROM onlineusers
WHERE id IN (
SELECT id FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
ORDER BY id
) u;
Hal lain yang perlu diingat adalah bahwa dokumentasi MySQL menyarankan bahwa jika terjadi kebuntuan, klien harus mencoba lagi secara otomatis. Anda dapat menambahkan logika ini ke kode klien Anda. (Katakanlah, 3 percobaan ulang pada kesalahan khusus ini sebelum menyerah).