Secara default, sebagian besar waktu Transaksi tidak dibatalkan / dibatalkan secara otomatis saat terjadi kesalahan. Ini biasanya bukan masalah selama Anda memiliki penanganan kesalahan yang tepat dan menelepon ROLLBACKdiri sendiri. Namun, kadang-kadang hal menjadi rumit, seperti dalam kasus kesalahan batch-dibatalkan, atau ketika menggunakan OPENQUERY(atau Server Terkait pada umumnya) dan kesalahan terjadi pada sistem jarak jauh. Sementara sebagian besar kesalahan dapat terjebak menggunakan TRY...CATCH, ada dua yang tidak bisa dijebak seperti itu (tidak bisa mengingat yang mana pada saat ini - meneliti). Dalam kasus ini, Anda harus menggunakan SET XACT_ABORT ONuntuk mengembalikan transaksi dengan benar.
SET XACT_ABORT ON menyebabkan SQL Server segera memutar kembali segala Transaksi (jika ada yang aktif) dan membatalkan kumpulan jika ada kesalahan. Pengaturan ini ada sebelum SQL Server 2005, yang memperkenalkan TRY...CATCHkonstruk. Sebagian besar, TRY...CATCHmenangani sebagian besar situasi dan sebagian besar kebutuhan usang XACT_ABORT ON. Namun, ketika menggunakan OPENQUERY(dan mungkin satu skenario lain yang saya tidak ingat saat ini), maka Anda masih harus menggunakan SET XACT_ABORT ON;.
Anda harus selalu memiliki penanganan kesalahan yang tepat, terutama saat menggunakan Transaksi. The TRY...CATCHmembangun, diperkenalkan pada SQL Server 2005, menyediakan sarana penanganan hampir semua situasi, menyambut perbaikan atas pengujian untuk @@ERRORsetelah setiap pernyataan, yang tidak membantu banyak dengan kesalahan batch-batal.
TRY...CATCHmemperkenalkan "negara" baru, namun. Ketika tidak menggunakan TRY...CATCHkonstruk, jika Anda memiliki Transaksi aktif dan terjadi kesalahan, maka ada beberapa jalur yang dapat diambil:
XACT_ABORT OFFdan kesalahan pembatalan pernyataan: Transaksi masih aktif dan pemrosesan dilanjutkan dengan pernyataan berikutnya , jika ada.
XACT_ABORT OFFdan sebagian besar kesalahan pembatalan bets: Transaksi masih aktif dan pemrosesan berlanjut dengan bets berikutnya , jika ada.
XACT_ABORT OFFdan kesalahan pembatalan bets tertentu: Transaksi dibatalkan dan pemrosesan dilanjutkan dengan bets berikutnya , jika ada.
XACT_ABORT ONdan kesalahan apa pun : Transaksi dibatalkan dan pemrosesan dilanjutkan dengan batch berikutnya , jika ada.
NAMUN, saat menggunakan TRY...CATCH, kesalahan yang dibatalkan batch tidak membatalkan batch, tetapi alih-alih mentransfer kontrol ke CATCHblok. Ketika XACT_ABORTadalah OFF, Transaksi akan tetap aktif sebagian besar waktu, dan Anda akan perlu COMMIT, atau paling mungkin, ROLLBACK. Tapi ketika menghadapi kesalahan batch-batal tertentu (seperti dengan OPENQUERY), atau ketika XACT_ABORTadalah ON, Transaksi akan berada dalam keadaan baru, "uncommitable". Dalam keadaan ini Anda tidak bisa COMMIT, Anda juga tidak bisa melakukan operasi DML. Semua dapat Anda lakukan adalah ROLLBACKdan SELECTpernyataan. Akan tetapi, dalam keadaan "tidak dapat diterima" ini, Transaksi dibatalkan karena kesalahan yang terjadi, dan mengeluarkannya ROLLBACKhanyalah formalitas, tetapi harus dilakukan.
Fungsi, XACT_STATE , dapat digunakan untuk menentukan apakah suatu Transaksi aktif, tidak dikomunikasikan, atau tidak ada. Dianjurkan (oleh beberapa orang, setidaknya) untuk memeriksa fungsi ini di CATCHblok untuk menentukan apakah hasilnya -1(yaitu uncommitable) alih-alih menguji jika @@TRANCOUNT > 0. Tetapi dengan XACT_ABORT ON, itu harus menjadi satu-satunya keadaan yang memungkinkan untuk dilakukan, sehingga tampaknya pengujian untuk @@TRANCOUNT > 0dan XACT_STATE() <> 0setara. Di sisi lain, ketika XACT_ABORTadalah OFFdan ada transaksi aktif, maka ada kemungkinan untuk memiliki keadaan baik 1atau -1di CATCHblok, yang memungkinkan untuk kemungkinan menerbitkan COMMITbukan ROLLBACK(meskipun, saya tidak bisa memikirkan kasus ketika seseorang inginCOMMITjika Transaksi berkomitmen). Informasi dan penelitian lebih lanjut tentang penggunaan XACT_STATE()dalam CATCHblok XACT_ABORT ONdapat ditemukan dalam jawaban saya untuk pertanyaan DBA.SE berikut: Dalam kasus apa transaksi dapat dilakukan dari dalam blok CATCH ketika XACT_ABORT disetel ke ON? . Harap perhatikan bahwa ada bug minor XACT_STATE()yang menyebabkannya salah 1dalam skenario tertentu: XACT_STATE () mengembalikan 1 ketika digunakan dalam SELECT dengan beberapa variabel sistem tetapi tanpa klausa FROM dari klausa
spNewBilling3melempar kesalahan, tetapi Anda tidak ingin memutar kembalispNewBilling2atauspNewBilling1, kemudian hanya menghapus[begin|rollback|commit] transaction createSavebillinginvoicedarispSavesomename.