Batas Waktu Transaksi SQL Server

9

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.

David Gray Wright
sumber

Jawaban:

20

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:

gbn
sumber
Masa depan menyapa! "Perhatikan bahwa sp_reset_connection tidak akan atau tidak menghapusnya, meskipun itu diiklankan untuk melakukannya" - Saya tidak percaya ini benar lagi dalam versi SQL Server terbaru?
kamilk
11

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_ABORTmenentukan apakah SQL Server akan mengembalikan transaksi jika terjadi kesalahan run-time. Standarnya SET XACT_ABORT OFFhanya 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.

Mark Storey-Smith
sumber
Saya menemukan, dengan beberapa Googling, cara untuk menemukan transaksi terbuka ketika hang terjadi - mungkin ini adalah solusi terbaik. Itu untuk menemukan apa yang menyebabkan transaksi tidak tertutup dalam kode dan memperbaiki lubang dalam kode. Untuk referensi bagi orang lain. DBCC OPENTRAN mengembalikan transaksi aktif tertua -> msdn.microsoft.com/en-us/library/ms182792.aspx Atau sesuatu yang lebih seperti ini? -> weblogs.sqlteam.com/mladenp/archive/2008/04/29/…
David Gray Wright
Saya selalu berpikir Erland tidak melakukan keadilan pada SET XACT_ABORT sommarskog.se/error-handling-I.html#XACT_ABORT
gbn