sql >> Databáze >  >> RDS >> Sqlserver

trigger a transakce na dočasných tabulkách

Nemyslím si, že rozumíte spouštěčům - spouštění spouště je spojeno s prohlášením, se kterým souvisí, spíše než s potvrzením transakce. Dva skripty:

Skript 1:

create table T1 (
    ID int not null,
    Val1 varchar(10) not null
)
go
create table T2 (
    ID int not null,
    Val2 varchar(10) not null
)
go
create trigger T_T1_I
on T1
after insert
as
    insert into T2 (ID,Val2) select ID,Val1 from inserted
go
begin transaction
insert into T1 (ID,Val1)
select 10,'abc'
go
RAISERROR('Run script 2 now',10,1) WITH NOWAIT
WAITFOR DELAY '00:01:00'
go
commit

Skript 2:

select * from T2 with (nolock)

Otevřete dvě připojení ke stejné DB, do každého připojení vložte jeden skript. Spusťte skript 1. Když se zobrazí zpráva "Spustit skript 2 nyní", přepněte na druhé připojení. Uvidíte, že můžete vybrat nepotvrzená data z T2, i když jsou tato data vložena spouštěčem. (To také znamená, že příslušné zámky jsou na T2 drženy skriptem 1, dokud se trigger neschválí).

Protože to znamená, že ekvivalent toho, co požadujete, je pouze vložit do základní tabulky a ponechat transakci otevřenou, můžete to udělat.

Pokud chcete před uživateli skrýt skutečný tvar tabulky, vytvořte pohled a zapište na to spouštěče pro aktualizaci základních tabulek. Jak je však uvedeno výše, jakmile provedete operaci DML proti pohledu, spouštěče se spustí a vy budete držet zámky na základní tabulce. V závislosti na úrovni izolace transakcí ostatních připojení mohou vidět vaše změny nebo být zablokováni, dokud transakce nebude potvrzena.



  1. Jaký je rozdíl mezi datovými typy sloupců MySQL BOOL a BOOLEAN?

  2. Získávání prázdných výsledků pro dotaz 'COUNT'/'GROUP BY' MySQL

  3. hibernate hql - vrátí aktualizovaný seznam ID řádků po provedení aktualizačního dotazu

  4. mysqli, připravené příkazy a příkazy INSERT-SELECT