Existe uma maneira de impedir que uma coluna computada não persistente seja atualizada em uma transação?
Eu montei um exemplo que mostra que essas colunas podem ser atualizadas ao usar funções não determinísticas (neste caso getutcdate()
). Isso não quebra os requisitos de consistência de uma transação? Eu tentei usar níveis de transação para evitar isso (serializável e instantâneo), o que não ajudou.
Consulta:
set nocount on;
create table dbo.TransactionTest (
[Timestamp] datetime,
IsUpdated as case when datediff(second, [Timestamp], getutcdate()) >= 1 then 1 else 0 end
);
insert into dbo.TransactionTest ([Timestamp]) values (getutcdate());
begin tran
select *
from dbo.TransactionTest;
waitfor delay '00:00:01';
select *
from dbo.TransactionTest;
rollback
drop table dbo.TransactionTest;
Resultados:
Timestamp IsUpdated
----------------------- -----------
2017-03-19 00:44:28.130 0
Timestamp IsUpdated
----------------------- -----------
2017-03-19 00:44:28.130 1
Há algumas perguntas diferentes aqui.
P: Posso forçar GETUTCDATE() a permanecer o mesmo durante uma transação?
Não. Se você tiver uma transação de longa duração, a hora mudará enquanto você trabalha. Isso não tem nada a ver com seu nível de isolamento, e mais a ver com o fato de que a vida não tem um botão de pausa. (Ainda. Tentei apontar o Freeze Ray do Dr. Horrible para o meu computador, mas isso só fez minhas unidades de estado sólido se tornarem ainda mais sólidas.)
P: Posso forçar funções não determinísticas a retornarem sempre o mesmo resultado?
Por definição, não. Se você pudesse, eles seriam determinísticos.
P: Se eu precisar que as datas/horas permaneçam estáticas durante uma transação, o que devo fazer?
Se você precisar apenas de um único valor, crie uma variável e defina seu valor no início de sua transação. Em sp_BlitzFirst, por exemplo, defino uma variável @StartSampleTime e continuo usando isso em todo o código.
Se você precisar de várias linhas, selecione os dados em um objeto permanente, como uma tabela de usuário ou uma tabela temporária, e consulte-os repetidamente durante a vida da transação.