Access
 sql >> Teknologi Basis Data >  >> RDS >> Access

TRANSACTION_MUTEX dan Akses Transaksi Multi-Sesi

Saya baru-baru ini menemukan TRANSACTION_MUTEX tinggi akumulasi waktu tunggu pada sistem klien. Saya tidak dapat mengingat kasus di mana saya melihat jenis menunggu ini berada di dekat bagian atas daftar "menunggu tinggi" dan saya ingin tahu tentang faktor apa yang dapat mendorong jenis waktu tunggu keseluruhan ini.

Definisi Buku Online dari TRANSACTION_MUTEX adalah bahwa itu "terjadi selama sinkronisasi akses ke transaksi oleh beberapa batch." Tidak banyak area di dalam mesin SQL Server yang mengekspos fungsionalitas jenis ini, jadi penyelidikan saya dipersempit ke teknologi berikut:

  • sp_getbindtoken yang tidak digunakan lagi dan sp_bindsession prosedur tersimpan sistem yang digunakan untuk menangani koneksi terikat
  • Transaksi terdistribusi
  • MARS (Beberapa Set Hasil Aktif)

Tujuan saya adalah menguji setiap teknologi dan melihat apakah itu memengaruhi TRANSACTION_MUTEX jenis tunggu.

Tes pertama yang saya lakukan menggunakan sp_getbindtoken yang sudah tidak digunakan lagi dan sp_bindsession prosedur tersimpan. sp_getbindtoken mengembalikan pengidentifikasi transaksi yang kemudian dapat digunakan oleh sp_bindsession untuk mengikat beberapa sesi bersama pada transaksi yang sama.

Sebelum setiap skenario pengujian, saya memastikan untuk menghapus statistik tunggu instance SQL Server pengujian saya:

DBCC SQLPERF('waitstats', CLEAR);
GO

Contoh pengujian SQL Server saya menjalankan SQL Server 2012 SP1 Developer Edition (11.0.3000). Saya menggunakan basis data sampel Kredit, meskipun Anda dapat menggunakan jenis basis data sampel lain seperti AdventureWorks jika Anda mau, karena skema dan distribusi data tidak secara langsung relevan dengan subjek artikel ini dan tidak diperlukan untuk mengemudi TRANSACTION_MUTEX waktu tunggu.

sp_getbindtoken / sp_bindsession

Di jendela sesi pertama SQL Server Management Studio, saya mengeksekusi kode berikut untuk memulai transaksi dan mengeluarkan token ikat untuk pendaftaran oleh sesi lain yang direncanakan:

USE Credit;
GO
 
BEGIN TRANSACTION;
 
DECLARE @out_token varchar(255);
 
EXECUTE sp_getbindtoken @out_token OUTPUT;
 
SELECT @out_token AS out_token;
GO

Ini mengembalikan @out_token dari S/Z5_GOHLaGY<^i]S9LXZ-5---.fE--- . Di dua jendela kueri SQL Server Management Studio terpisah, saya mengeksekusi kode berikut untuk bergabung ke sesi yang ada (mengakses transaksi bersama):

USE Credit;
GO
 
EXEC sp_bindsession 'S/Z5_GOHLaGY<^i]S9LXZ-5---.fE---';

Dan dengan jendela sesi pertama masih terbuka, saya memulai loop berikut untuk memperbarui tabel tabel biaya dengan tanggal pengisian yang sama dengan tanggal dan waktu saat ini, dan kemudian menjalankan logika yang sama di dua jendela lainnya (tiga sesi aktif di lingkaran):

WHILE 1 = 1 
BEGIN
    UPDATE  dbo.charge
    SET     charge_dt = SYSDATETIME();
END

Setelah beberapa detik, saya membatalkan setiap kueri yang dieksekusi. Dari tiga sesi, hanya satu yang benar-benar dapat melakukan pembaruan – meskipun dua sesi lainnya secara aktif bergabung ke transaksi yang sama. Dan jika saya melihat TRANSACTION_MUTEX tipe tunggu, saya dapat melihat bahwa itu memang meningkat:

SELECT  [wait_type],
        [waiting_tasks_count],
        [wait_time_ms],
        [max_wait_time_ms],
        [signal_wait_time_ms]
FROM sys.dm_os_wait_stats
WHERE wait_type = 'TRANSACTION_MUTEX';

Hasil untuk tes khusus ini adalah sebagai berikut:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    2                     181732         93899              0

Jadi saya melihat ada dua tugas yang menunggu (dua sesi yang secara bersamaan mencoba memperbarui tabel yang sama melalui loop). Karena saya belum menjalankan SET NOCOUNT ON , saya dapat melihat bahwa hanya UPDATE . yang dieksekusi pertama kali loop mendapat perubahan. Saya mencoba teknik serupa ini menggunakan beberapa variasi berbeda (misalnya – empat sesi keseluruhan, dengan tiga menunggu) – dan TRANSACTION_MUTEX incrementing menunjukkan perilaku yang sama. Saya juga melihat TRANSACTION_MUTEX akumulasi ketika secara bersamaan memperbarui tabel yang berbeda untuk setiap sesi – jadi modifikasi terhadap objek yang sama dalam satu lingkaran tidak diperlukan untuk mereproduksi TRANSACTION_MUTEX akumulasi waktu tunggu.

Transaksi terdistribusi

Pengujian saya berikutnya melibatkan melihat apakah TRANSACTION_MUTEX waktu tunggu bertambah untuk transaksi terdistribusi. Untuk pengujian ini, saya menggunakan dua instance SQL Server dan server tertaut yang terhubung di antara keduanya. MS DTC berjalan dan dikonfigurasi dengan benar, dan saya mengeksekusi kode berikut yang melakukan DELETE lokal dan DELETE remote jarak jauh melalui server tertaut dan kemudian mengembalikan perubahan:

USE Credit;
GO
 
SET XACT_ABORT ON;
 
-- Assumes MS DTC service is available, running, properly configured
BEGIN DISTRIBUTED TRANSACTION;
 
DELETE [dbo].[charge] WHERE charge_no = 1;
DELETE [JOSEPHSACK-PC\AUGUSTUS].[Credit].[dbo].[charge] WHERE charge_no = 1;
 
ROLLBACK TRANSACTION;

TRANSACTION_MUTEX tidak menunjukkan aktivitas di server lokal:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    0                     0              0                  0

Namun jumlah tugas menunggu bertambah di server jarak jauh:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    1                     0              0                  0

Jadi harapan saya untuk melihat ini dikonfirmasi – mengingat bahwa kami memiliki satu transaksi terdistribusi dengan lebih dari satu sesi yang terlibat dalam beberapa cara dengan transaksi yang sama.

MARS (Beberapa Set Hasil Aktif)

Bagaimana dengan penggunaan Multiple Active Result Sets (MARS)? Apakah kami juga berharap untuk melihat TRANSACTION_MUTEX terakumulasi ketika dikaitkan dengan penggunaan MARS?

Untuk ini, saya menggunakan kode aplikasi konsol C# berikut yang diuji dari Microsoft Visual Studio terhadap contoh SQL Server 2012 saya dan database Kredit. Logika dari apa yang sebenarnya saya lakukan tidak terlalu berguna (mengembalikan satu baris dari setiap tabel), tetapi pembaca data berada pada koneksi yang sama dan atribut koneksi MultipleActiveResultSets disetel ke true, jadi cukup untuk memverifikasi apakah MARS memang bisa mengemudikan TRANSACTION_MUTEX akumulasi juga:

string ConnString = @"Server=.;Database=Credit;Trusted_Connection=True;MultipleActiveResultSets=true;";
SqlConnection MARSCon = new SqlConnection(ConnString);
 
MARSCon.Open();
 
SqlCommand MARSCmd1 = new SqlCommand("SELECT payment_no FROM dbo.payment;", MARSCon);
SqlCommand MARSCmd2 = new SqlCommand("SELECT charge_no FROM dbo.charge;", MARSCon);
 
SqlDataReader MARSReader1 = MARSCmd1.ExecuteReader();
SqlDataReader MARSReader2 = MARSCmd2.ExecuteReader();
 
MARSReader1.Read();
MARSReader2.Read();
 
Console.WriteLine("\t{0}", MARSReader1[0]);
Console.WriteLine("\t{0}", MARSReader2[0]);

Setelah mengeksekusi kode ini, saya melihat akumulasi berikut untuk TRANSACTION_MUTEX :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    8                     2              0                  0

Jadi seperti yang Anda lihat, aktivitas MARS (meskipun implementasinya sepele) menyebabkan peningkatan di TRANSACTION_MUTEX akumulasi tipe tunggu. Dan atribut string koneksi itu sendiri tidak mendorong ini, implementasi sebenarnya yang melakukannya. Misalnya, saya menghapus implementasi pembaca kedua dan hanya mempertahankan satu pembaca dengan MultipleActiveResultSets=true , dan seperti yang diharapkan, tidak ada TRANSACTION_MUTEX akumulasi waktu tunggu.

Kesimpulan

Jika Anda melihat TRANSACTION_MUTEX tinggi menunggu di lingkungan Anda, saya harap posting ini memberi Anda beberapa wawasan tentang tiga jalan untuk dijelajahi - untuk menentukan dari mana menunggu ini berasal, dan apakah itu perlu atau tidak.


No
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 10 Tips Microsoft Access untuk Membuat Query Pilihan

  2. Bergabunglah dengan Saya dengan Tamu Khusus Michal Bar dari Tim MS Access!

  3. Membuat Kontrol Akses Berbasis Peran di MongoDB

  4. Cara Menghentikan atau Mengontrol Penanda Pemeriksaan Kesalahan Microsoft Access

  5. Parameter String Koneksi untuk Sumber File Teks