it-swarm-id.com

Batas Waktu Transaksi SQL Server

Apakah ada cara di SQL Server 2008 R2 untuk menyebabkan batas waktu untuk modifikasi database yang melibatkan transaksi? Kami memiliki skenario di mana kode aplikasi kami hang atau melempar pengecualian dan gagal melakukan rollback atau commit. Ini kemudian menyebabkan sesi lain hang menunggu transaksi selesai.

9

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:

20
gbn

Saya menjawab ini dengan ragu-ragu karena tidak ada informasi yang cukup dalam deskripsi masalah Anda untuk 100% yakin ini adalah saran terbaik. "Hang atau melempar pengecualian" menunjukkan sumber masalah tidak dipahami dengan baik, 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. Default SET 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>.

Sering dikutip Erland Sommarskog's artikel tentang penanganan kesalahan dalam 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.

11