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 (example@sqldat.com 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