Jika Anda menerima pesan kesalahan 3902, Level 16, yang berbunyi "Permintaan TRANSAKSI COMMIT tidak memiliki TRANSAKSI AWAL yang sesuai", mungkin karena Anda memiliki COMMIT
yang tersesat pernyataan.
Anda bisa mendapatkan ini karena menerapkan penanganan kesalahan, dan lupa bahwa Anda telah melakukan atau membatalkan transaksi di tempat lain dalam kode Anda.
Contoh Kesalahan
Berikut adalah contoh sederhana untuk menunjukkan kesalahan:
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Hasil:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Ini akan terjadi jika SET IMPLICIT_TRANSACTIONS
adalah OFF
. Lihat di bawah untuk mengetahui apa yang terjadi ketika SET IMPLICIT_TRANSACTIONS
adalah ON
.
Contoh Kesalahan karena Penanganan Kesalahan
Anda bisa mendapatkan ini karena menerapkan penanganan kesalahan, dan lupa bahwa Anda telah melakukan atau membatalkan transaksi di tempat lain dalam kode Anda.
Misalnya:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
COMMIT TRANSACTION;
Hasil:
(1 row affected) (1 row affected) (1 row affected) Msg 3902, Level 16, State 1, Line 20 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Dalam hal ini, saya sudah memiliki COMMIT TRANSACTION
di TRY
memblokir. Jadi pada saat COMMIT TRANSACTION
kedua ditemui, transaksi telah dilakukan.
Kami akan melihat hal yang sama bahkan jika transaksi mengalami kesalahan, dan dibatalkan. Rollback akan mengakhiri transaksi, dan oleh karena itu, tidak ada lagi COMMIT
pernyataan diperlukan.
Jadi untuk memperbaiki masalah ini, kami cukup menghapus COMMIT TRANSACTION
terakhir , dan kode transaksi akan terlihat seperti ini:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Transaksi Implisit
Jika Anda mengaktifkan transaksi implisit, Anda mungkin mendapatkan hasil yang berbeda dengan contoh pertama.
Jika kita menyetel IMPLICIT_TRANSACTIONS
ke ON
, inilah yang kami dapatkan:
SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Hasil:
+---------------------------------+----------------+ | ProductName | ProductPrice | |---------------------------------+----------------| | Left handed screwdriver | 25.99 | | Long Weight (blue) | 14.75 | | Long Weight (green) | 11.99 | | Sledge Hammer | 33.49 | | Chainsaw | 245.00 | | Straw Dog Box | 55.99 | | Bottomless Coffee Mugs (4 Pack) | 9.99 | +---------------------------------+----------------+ (7 rows affected)
Tidak ada kesalahan yang terjadi.
Ini karena, pernyataan T-SQL tertentu secara otomatis memulai transaksi saat dijalankan. Seolah-olah mereka didahului oleh BEGIN TRANSACTION
yang tidak terlihat pernyataan.
Ketika IMPLICIT_TRANSACTIONS
adalah OFF
, pernyataan ini secara otomatis dilakukan. Seolah-olah mereka digantikan oleh COMMIT TRANSACTION
yang tidak terlihat penyataan. Dalam skenario ini, transaksi dalam mode autocommit.
Ketika IMPLICIT_TRANSACTIONS
adalah ON
, tidak ada COMMIT TRANSACTION
yang tidak terlihat penyataan. Pernyataan ini masih dimulai oleh BEGIN TRANSACTION
yang tidak terlihat , tetapi harus diakhiri secara eksplisit.
Transaksi implisit tetap berlangsung hingga transaksi dilakukan secara eksplisit atau dibatalkan secara eksplisit.
Oleh karena itu, dalam contoh ini, COMMIT TRANSACTION
kami yang tersesat pernyataan sebenarnya diperlukan untuk mengakhiri transaksi implisit.