Memperluas jawaban Mark ...
Ketika peristiwa batas waktu klien terjadi (misalnya. Net CommandTimeout), klien mengirim "ABORT" ke SQL Server. SQL Server kemudian hanya meninggalkan pemrosesan permintaan. Tidak ada transaksi yang dibatalkan, tidak ada kunci yang dirilis.
Sekarang, koneksi dikembalikan ke kumpulan koneksi, sehingga tidak ditutup pada SQL Server. Jika ini pernah terjadi (melalui KILL atau klien reboot dll) maka transaksi + kunci akan dihapus. Perhatikan bahwa sp_reset_connection tidak akan atau tidak menghapusnya, meskipun diiklankan untuk melakukannya
Detritus dari aborsi ini akan menghalangi proses lain.
Cara untuk membuat transaksi yang jelas dari SQL Server + mengunci pada batas waktu klien (ketat, peristiwa ABORT) adalah dengan menggunakan SET XACT_ABORT ON.
Anda dapat memverifikasi ini dengan membuka 2 jendela permintaan di SSMS:
Jendela 1:
Dalam menu Permintaan .. Opsi Permintaan mengatur batas waktu 5 detik kemudian jalankan ini
BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout
Jendela 2, ini akan menunggu selamanya (atau tekan batas waktu Anda)
SELECT * FROM sometable
SET XACT_ABORT ON juga memiliki efek samping yang menarik:
- @@ TRANCOUNT diatur ke nol pada rollback implisit tetapi kesalahan 266 ditekan (ini terjadi jika @@ TRANCOUNT berbeda saat masuk dan keluar dari proc yang disimpan)
- XACT_STATE akan menjadi -1 (ini "dikutuk")
Kombinasi ini berarti bahwa Anda tidak dapat menggunakan SAVEPOINTS (walaupun, saya tidak dapat mengingat perilaku yang tepat) untuk sebagian komitmen / kembalikan. Yang cocok untukku
Tautan SO pada SET XACT_ABORT:
Pada procs tersimpan bersarang:
Pada sp_reset_connection:
Saya menjawab ini dengan ragu-ragu karena tidak ada informasi yang cukup dalam deskripsi masalah Anda untuk 100% yakin ini adalah saran terbaik. "Menggantung atau melempar pengecualian" menunjukkan bahwa sumber masalah tidak dipahami dengan benar, jadi lanjutkan dengan hati-hati.
Solusi paling sederhana untuk ini mungkin
SET XACT_ABORT ON
.XACT_ABORT
menentukan apakah SQL Server akan mengembalikan transaksi jika terjadi kesalahan run-time. StandarnyaSET XACT_ABORT OFF
hanya akan mengembalikan pernyataan yang menyebabkan kesalahan, membiarkan semua transaksi induk terbuka.Efek samping "gotcha" dari pengaturan default adalah bahwa timeout dapat menyebabkan masalah yang sama persis, transaksi terbuka yang merupakan tanggung jawab klien untuk ditangani dan dikembalikan. Jika klien tidak mencoba / menangkap / mengembalikan, transaksi akan tetap terbuka sampai dihadiri dengan (dan saya kutip @gbn) ultra-kekerasan
KILL <spid>
.Seringkali mengutip artikel Erland Sommarskog tentang penanganan kesalahan di SQL Server berisi semua latar belakang dan strategi yang Anda butuhkan untuk menangani skenario ini dan banyak lagi.
Sunting (komentar berikut): Untuk mengidentifikasi transaksi terbuka, sp_whoisactive mungkin fitur yang paling lengkap.
sumber