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: