Pengantar
Ada situasi ketika aplikasi menyimpan koneksi database untuk jangka waktu yang lama. Sepertinya tidak penting. Namun, jika aplikasi ini membuat banyak koneksi atau ada beberapa aplikasi dengan perilaku seperti itu — keadaan menjadi lebih buruk.
Artikel ini bukan tutorial. Ini menjelaskan kemungkinan solusi untuk masalah ini. Seperti biasa, saya akan senang mendengar solusi alternatif apa pun.
Solusi
1. Buat prosedur tersimpan yang menutup semua koneksi atau koneksi pengguna tertentu ke database yang ditentukan:
USE [DATABASE_NAME] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [srv].[KillConnect] @databasename nvarchar(255), -- database @loginname nvarchar(255)=NULL -- login details AS BEGIN /* deletes connections for the specified database and login details access */ SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; if(@databasename is null) begin ;THROW 50000, 'A database is not specified!', 0; end else begin declare @dbid int=db_id(@databasename); if(@dbid is NULL) begin ;THROW 50000, 'The database does not exist!', 0; end else if @dbid <= 4 begin ;THROW 50000, 'To delete connections to a system database is forbidden!', 0; end else begin declare @query nvarchar(max); set @query = ''; select @query=coalesce(@query,',' ) +'kill ' +convert(varchar, spid) +'; ' from master..sysprocesses where dbid=db_id(@databasename) and spid<>@@SPID and ([email protected] or @loginname is null); if len(@query) > 0 begin begin try exec(@query); end try begin catch end catch end end end END GO
Prosedur tersimpan ini membantu menonaktifkan semua koneksi ke database atau pengguna tertentu secara manual untuk tindakan lebih lanjut dengan database.
2. Buat prosedur tersimpan untuk menghapus semua proses yang macet.
USE [DATABASE_NAME] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [srv].[KillFullOldConnect] AS BEGIN /* It deletes the connections which were executed a day ago. Attention! System databases such as master, tempdb, model and msdb do not take part in this process. However, it does not affect database distribution for replication. */ SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; declare @query nvarchar(max); set @query = ''; select @query=coalesce(@query,',' ) +'kill ' +convert(varchar, spid) +'; ' from master..sysprocesses where dbid>4 and [last_batch]<dateadd(day,-1,getdate()) order by [last_batch] if len(@query) > 0 begin begin try exec(@query); end try begin catch end catch end END GO
Prosedur tersimpan ini menghapus koneksi yang diselesaikan lebih dari 24 jam yang lalu. Selain itu, prosedur ini tidak mempengaruhi database sistem utama (master, tempdb, model, dan msdb). Jika Anda mencoba mengakses database saat koneksi dinonaktifkan, koneksi baru untuk aplikasi ini akan dibuat.
Sekarang, perlu menjalankan prosedur tersimpan dalam tugas Agen sekali sehari:
exec [DATABASE_NAME].[srv].[KillFullOldConnect];
Akan lebih baik untuk membungkus kueri ini ke dalam blok try-catch untuk memproses kemungkinan panggilan untuk pengecualian.
Hasil
Dalam artikel ini, saya telah menganalisis bagaimana menerapkan prosedur tersimpan pada penutupan koneksi ke database (semua atau pengguna tertentu) dan untuk menghapus proses yang macet pada contoh tertentu. Selain itu, saya telah menjelajahi contoh tertentu bagaimana menjalankan tugas secara otomatis pada penghapusan proses yang macet setiap hari. Ini memungkinkan penurunan jumlah koneksi 'mati' ke server. Penghapusan semua koneksi ke database memungkinkan Anda untuk mengubah beberapa properti, serta menutup proses yang menyebabkan masalah apa pun.
Referensi:
» sysprocesses
» kill
» db_id
» @@SPID