Funcionalidade de Timeout com DataServer SQL – parte I

Escrito por Marcos Kirchner em 3 de junho de 2009, 08:26h

Os produtos Datasul EMS 2, EMS 5 e HCM possuem um recurso chamado Timeout, quando utilizados com bancos de dados Progress ou Oracle. O Timeout é uma funcionalidade que desconecta usuários inativos no sistema por muito tempo e também impede que cada usuário abra mais de uma sessão de cada produto.

Os dois principais benefícios deste recurso são:

  • racionalização de uso das licenças do produto Datasul, impedindo que cada usuário utilize mais de uma licença e desconectando usuários inativos para liberar as licenças utilizadas;
  • economia de recursos computacionais, desconectando usuários ociosos e liberando os recursos associados.

Este recurso não está disponível para clientes que utilizam bancos de dados SQL Server com os produtos Datasul. Felizmente, não é difícil implementar uma funcionalidade similar utilizando comandos nativos do SQL Server.

A Dynamic Management View (DMV) sys.dm_exec_sessions disponibiliza todas as informações necessárias para implementar um Timeout simples. As colunas mais interessantes neste caso são:

  • login_name
  • program_name
  • last_request_start_time
  • client_interface_name - API utilizada para conexão (sempre ODBC para o DataServer)
  • is_user_process – processo interno do SQL Server (= 0) ou um processo do usuário (= 1)
  • host_name
  • host_process_id

Deve-se atentar que o DataServer normalmente utiliza mais de uma conexão para cada usuário. Para calcular o tempo de inatividade do usuário, é necessário verificar entre todas as conexões daquele usuário qual delas foi utilizada mais recentemente (que está ociosa a menos tempo). Abaixo um exemplo de Stored Procedure que desconecta usuários ociosos do servidor.

 

ATENÇÃO: este código é uma ilustração dos conceitos abordados neste Post. Não há suporte para este código. Só utilize este código se entender exatamente o que ele faz e estiver satisfeito com o resultado.

/*
Permissões mínimas necessárias:

- VIEW SERVER STATE on server
- processadmin server role
*/

CREATE PROCEDURE dbo.ProcDatasulTimeout (
    @TimeoutInMinutes INT
)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @KillCmd NVARCHAR(MAX);

    SELECT @KillCmd =
    (SELECT 'KILL ' + CAST(session_id AS VARCHAR(10)) + '; '
    FROM sys.dm_exec_sessions s1
    WHERE EXISTS
        (SELECT s2.host_name, s2.host_process_id, s2.login_name
        FROM sys.dm_exec_sessions s2
        WHERE program_name = 'Datasul EMS 2' AND client_interface_name = 'ODBC' AND
            is_user_process = 1 AND s1.host_name = s2.host_name AND
            s1.host_process_id = s2.host_process_id AND
            s1.login_name = s2.login_name
        GROUP BY s2.host_name, s2.host_process_id, s2.login_name
        HAVING DATEDIFF(mi, MAX(s2.last_request_start_time), GETDATE())
            > @TimeoutInMinutes)
    FOR XML PATH(''));

    EXECUTE sp_executesql @KillCmd;
END;

 

Esta Stored Procedure aceita um tempo, em minutos, como parâmetro, e encerra (KILL) as conexões dos usuários que estão conectados a mais tempo do que o valor informado. Atente que para poder filtrar pelo nome da aplicação, é necesário informar um nome de aplicação no momento da conexão.

Este código não impede que um usuário abra várias sessões do produto, apenas desconecta sessões ociosas. No próximo post da série veremos como impedir a abertura de várias sessões do mesmo produto.

Categorias: Banco de dados | SQL Server

Tags:

Comentários (1) -

em 7 de junho de 2009, 21:57h

Legal a query, bem criativa!

Paulo

Comentar




biuquote
  • Comentário
  • Pré-visualização
Loading


Acesso LogMeIn

Informe o código PIN: