Eu queria saber se é possível criar uma tabela que seja realmente rápida e temporária (basicamente uma que resida na memória RAM) no MS SQL Server 2005 ou posterior para fins de comunicação entre softwares? Todas as funcionalidades normais de bloqueio também funcionam com essas tabelas, se possível? Temos um software antigo que deseja receber mensagens através do banco de dados e atualmente está usando apenas uma tabela normal, embora realmente não precise preservar seu estado durante as reinicializações. Também gostaríamos de usar procedimentos TSQL armazenados nessa tabela.
Início
/
user-284402
The amateur programmer's questions
The amateur programmer
Asked:
2023-12-22 19:03:07 +0800 CST
Eu queria tornar a consulta antiga a seguir segura contra corridas de dados ao executá-las em paralelo. A consulta verifica se existe uma linha em uma tabela usando critérios específicos e se tal linha não existir, insere uma nova com novos dados. A consulta antiga está colada abaixo:
BEGIN
DECLARE @txtPer VARCHAR(MAX) = @nro;
DECLARE @txtCmin VARCHAR(MAX) = @min;
DECLARE @txtCmax VARCHAR(MAX) = @max;
IF NOT EXISTS (SELECT 1 FROM SEND WHERE MSG LIKE (@txtPer + '%') AND STATE < 2 AND ID = 1)
BEGIN
----Time of check is not time of use
----Someone could possibly do another insert before this == data race
INSERT INTO SEND (SNDID, ID, MSGCODE, MSG, STATE, INFO, INFO_TEXT, CHANGEDATE, CREATEDATE)
SELECT MAX(SNDID)+10,1,1,(@txtPer + @txtCmin + ' ' + @txtCmax),0,0,' ',getdate(),getdate() FROM SEND
END
END
Eu criei uma nova versão que é um pouco mais limpa e usa bloqueio de tabela exclusivo:
BEGIN TRANSACTION;
DECLARE @txtPer VARCHAR(MAX) = @nro;
DECLARE @txtCmin VARCHAR(MAX) = @min;
DECLARE @txtCmax VARCHAR(MAX) = @max;
DECLARE @IdMax INT
--Get MAX and simultaneously acquire lock for the table to prevent modifications during this transaction?
SELECT @IdMax=MAX(SNDID) FROM SEND WITH(TABLOCKX)
IF NOT EXISTS(SELECT 1 FROM SEND WHERE MSG LIKE (@txtPer + '%') AND STATE < 2 AND ID = 1)
BEGIN
INSERT INTO SEND (SNDID, ID, MSGCODE, MSG, STATE, INFO, INFO_TEXT, CHANGEDATE, CREATEDATE)
VALUES((@IdMax + 10),1,1,(@txtPer + @txtCmin + ' ' + @txtCmax),0,0,' ',getdate(),getdate())
END
COMMIT; --writes potential change and releases table lock?
Meu entendimento está correto de que o bloqueio de tabela adquirido durante SELECT MAX()
a operação (e possivelmente outros na mesma transação) é mantido até que toda a transação seja finalizada com a COMMIT
instrução? DB é um antigo MS SQL Server 2005.