Salah satu cara untuk mengatasi kebuntuan adalah memiliki mekanisme coba lagi yang menunggu interval acak dan mencoba menjalankan transaksi lagi. Interval acak diperlukan agar transaksi yang bertabrakan tidak terus-menerus saling bertabrakan, menyebabkan apa yang disebut kunci langsung - sesuatu yang bahkan lebih buruk untuk di-debug. Sebenarnya sebagian besar aplikasi yang kompleks akan membutuhkan mekanisme coba ulang seperti itu cepat atau lambat ketika mereka perlu menangani kegagalan serialisasi transaksi.
Tentu saja jika Anda dapat menentukan penyebab kebuntuan biasanya jauh lebih baik untuk menghilangkannya atau akan kembali untuk menggigitmu. Untuk hampir semua kasus, bahkan ketika kondisi kebuntuan jarang terjadi, sedikit throughput dan overhead pengkodean untuk mendapatkan kunci dalam urutan deterministik atau mendapatkan lebih banyak kunci berbutir kasar sangat berharga untuk menghindari hit latency besar sesekali dan tebing kinerja yang tiba-tiba. saat menskalakan konkurensi.
Ketika Anda secara konsisten mendapatkan dua pernyataan INSERT yang menemui jalan buntu, kemungkinan besar itu adalah masalah urutan penyisipan indeks yang unik. Coba misalnya berikut ini di dua jendela perintah psql:
Thread A | Thread B
BEGIN; | BEGIN;
| INSERT uniq=1;
INSERT uniq=2; |
| INSERT uniq=2;
| block waiting for thread A to commit or rollback, to
| see if this is an unique key error.
INSERT uniq=1; |
blocks waiting |
for thread B, |
DEADLOCK |
V
Biasanya tindakan terbaik untuk menyelesaikan ini adalah dengan mencari tahu objek induk yang menjaga semua transaksi tersebut. Sebagian besar aplikasi memiliki satu atau dua entitas utama, seperti pengguna atau akun, yang merupakan kandidat yang baik untuk ini. Maka yang Anda butuhkan adalah untuk setiap transaksi untuk mendapatkan kunci pada entitas utama yang disentuhnya melalui SELECT ... FOR UPDATE. Atau jika menyentuh beberapa, dapatkan kunci pada semuanya tetapi dalam urutan yang sama setiap saat (urutkan dengan kunci utama adalah pilihan yang baik).