Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara Memperbaiki "Permintaan TRANSAKSI KOMIT tidak memiliki TRANSAKSI AWAL yang sesuai" di SQL Server

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Penginstalan dan Konfigurasi SQL Server Log Pengiriman &Pemulihan Bencana -4

  2. SQL Server 2012 meminta data Access 2007 menggunakan kesalahan OPENROWSET

  3. Hitung total berjalan / saldo berjalan

  4. Cara Menonaktifkan Semua Pemicu di Database SQL Server

  5. Php memanggil skrip database cadangan sqlserver, file cadangan dibuat dan kemudian dihapus