Pertanyaan Dukungan ORM untuk Menangani Deadlock


Apakah Anda tahu alat ORM apa pun yang menawarkan pemulihan kebuntuan? Saya tahu deadlock adalah hal yang buruk tetapi kadang-kadang sistem apapun akan menderita karena jumlah beban yang tepat. Di Sql Server, pesan kebuntuan mengatakan "Jalankan kembali transaksi" jadi saya akan curiga bahwa rerunning pernyataan kebuntuan adalah fitur yang diinginkan pada ORM.


7
2018-02-27 15:20


asal


Jawaban:


Saya tidak tahu ada dukungan alat ORM khusus untuk secara otomatis mengatur ulang transaksi yang gagal karena deadlock. Namun saya tidak berpikir bahwa ORM membuat berurusan dengan masalah penguncian / deadlocking yang sangat berbeda. Pertama, Anda harus menganalisis akar penyebab kebuntuan Anda, lalu mendesain ulang transaksi dan kueri Anda dengan cara yang dapat dihindari atau setidaknya dikurangi. Ada banyak pilihan untuk perbaikan, seperti memilih tingkat isolasi yang tepat untuk (bagian) dari transaksi Anda, menggunakan petunjuk kunci, dll. Ini lebih bergantung pada sistem basis data Anda pada ORM Anda. Tentu saja ini membantu jika ORM Anda memungkinkan Anda untuk menggunakan prosedur tersimpan untuk beberapa perintah yang disempurnakan, dll.

Jika ini tidak membantu untuk menghindari deadlock sepenuhnya, atau Anda tidak punya waktu untuk mengimplementasikan dan menguji perbaikan yang sebenarnya sekarang, tentu saja Anda dapat menempatkan try / catch sekitar save / commit / persist Anda atau panggilan apa pun, periksa kecuali jika mereka menunjukkan bahwa transaksi gagal adalah "korban deadlock", dan kemudian hanya ingat save / commit / bertahan setelah beberapa detik tidur. Menunggu beberapa detik adalah ide yang bagus karena deadlock sering merupakan indikasi bahwa ada puncak transaksi sementara yang bersaing untuk sumber daya yang sama, dan menjalankan kembali transaksi yang sama dengan cepat lagi dan lagi mungkin akan memperburuk keadaan.

Untuk alasan yang sama Anda mungkin ingin memastikan bahwa Anda hanya mencoba sekali untuk menjalankan kembali transaksi yang sama.

Dalam skenario dunia nyata, kami pernah menerapkan solusi semacam ini, dan sekitar 80% dari "deadlock victim" berhasil pada langkah kedua. Tapi saya sangat menyarankan untuk menggali lebih dalam untuk memperbaiki alasan sebenarnya untuk deadlocking, karena masalah ini biasanya meningkat secara eksponensial dengan jumlah pengguna. Semoga itu membantu.


4
2018-03-01 19:01



Deadlock harus diharapkan, dan SQL Server tampaknya lebih buruk di bagian depan ini daripada server database lainnya. Pertama, Anda harus mencoba untuk meminimalkan kebuntuan Anda. Coba gunakan SQL Server Profiler untuk mencari tahu mengapa itu terjadi dan apa yang dapat Anda lakukan. Selanjutnya, konfigurasikan ORM Anda agar tidak terbaca setelah melakukan pembaruan dalam transaksi yang sama, jika memungkinkan. Akhirnya, setelah Anda selesai melakukannya, jika Anda menggunakan Spring dan Hibernate bersama-sama, Anda dapat memasukkan interceptor untuk mengawasi situasi ini. Perluas MethodInterceptor dan letakkan di kacang Spring Anda di bawah interceptorNames. Ketika interceptor dijalankan, gunakan invocation.proceed () untuk melakukan transaksi. Tangkap pengecualian apa pun, dan tentukan beberapa kali Anda ingin mencoba lagi.


1
2018-03-01 19:05



Mapper o / r tidak dapat mendeteksi ini, karena kebuntuan selalu terjadi di dalam DBMS, yang bisa disebabkan oleh kunci yang disetel oleh utas atau aplikasi lain.

Untuk memastikan potongan kode tidak membuat kebuntuan, selalu gunakan aturan ini: - lakukan pengambilan di luar transaksi. Jadi, ambil dulu, lalu lakukan pemrosesan kemudian lakukan pernyataan DML seperti sisipkan, hapus dan perbarui - setiap tindakan di dalam metode atau serangkaian metode yang berisi / bekerja dengan transaksi harus menggunakan koneksi yang sama ke database. Ini diperlukan karena misalnya menulis kunci diabaikan oleh pernyataan yang dieksekusi melalui koneksi yang sama (karena koneksi yang sama mengatur kunci;)).

Seringkali, kebuntuan terjadi karena salah satu kode mengambil data di dalam transaksi yang menyebabkan sambungan BARU dibuka (yang harus menunggu kunci) atau menggunakan koneksi yang berbeda untuk laporan dalam transaksi.


0
2018-03-04 11:59



Saya memiliki tampilan cepat (tidak diragukan lagi Anda memiliki terlalu) dan tidak bisa menemukan apa pun yang menunjukkan bahwa hibernate setidaknya menawarkan ini. Ini mungkin karena ORM menganggap ini di luar lingkup masalah yang ingin mereka pecahkan.

Jika Anda mengalami masalah dengan deadlock tentu mengikuti beberapa saran yang diposting di sini untuk mencoba dan menyelesaikannya. Setelah itu Anda hanya perlu memastikan semua kode akses database Anda dibungkus dengan sesuatu yang dapat mendeteksi kebuntuan dan mencoba kembali transaksi.


0
2018-03-07 10:01



Satu sistem yang saya kerjakan didasarkan pada "perintah" yang kemudian berkomitmen ke basis data saat pengguna menekan simpan, itu berfungsi seperti ini:

While(true)
   start a database transaction
   Foreach command to process
      read data the command need into objects
      update the object by calling the command.run method
   EndForeach
   Save the objects to the database
   If not deadlock
     commit the database transaction
    we are done
   Else 
     abort the database transaction
    log deadlock and try again
   EndIf
EndWhile

Anda mungkin dapat melakukan sesuatu seperti dengan ORM apa pun; kami menggunakan sistem akses data di rumah, karena ORM terlalu baru pada saat itu.

Kami menjalankan perintah di luar transaksi saat pengguna berinteraksi dengan sistem. Kemudian jalankan kembali seperti di atas (ketika Anda menggunakan "save") untuk mengatasi perubahan yang dilakukan orang lain. Karena kami sudah memiliki ideal yang baik dari baris perintah akan berubah, kami bahkan bisa menggunakan petunjuk penguncian atau "pilih untuk pembaruan" untuk mengambil semua kunci tulis yang kami butuhkan pada awal transaksi. (Kami korslet set baris diperbarui untuk mengurangi jumlah deadlock bahkan lebih)


0
2018-03-03 15:38