Transaktion mit Read Committed Isolation Level und Tabelle Constraints
-
06-09-2019 - |
Frage
Haben Einschränkungen Tabelle in derselben Transaktion ausführen?
Ich habe eine Transaktion mit Read Committed-Isolationsstufe, die einige Zeilen in einer Tabelle einfügt. Der Tisch hat eine Einschränkung auf, dass eine Funktion aufruft, die wiederum einige Zeilen aus derselben Tabelle auswählt.
Es sieht aus wie die Funktion läuft, ohne etwas über die Transaktion zu wissen, und die Auswahl in der Funktion gibt Zeilen in der Tabelle, die dort vor der Transaktion war.
Gibt es eine Abhilfe oder bin ich etwas fehlt? Danke.
Hier sind die Codes für die Transaktion und die Einschränkung:
insert into Treasury.DariaftPardakhtDarkhastFaktor
(DarkhastFaktor, DariaftPardakht, Mablagh, CodeVazeiat,
ZamaneTakhsiseFaktor, MarkazPakhsh, ShomarehFaktor, User)
values
(@DarkhastFaktor, @DariaftPardakht, @Mablagh, @CodeVazeiat,
@ZamaneTakhsiseFaktor, @MarkazPakhsh, @ShomarehFaktor, @User);
constraint expression (enforce for inserts and updates):
([Treasury].[ufnCheckDarkhastFaktorMablaghConstraint]([DarkhastFaktor])=(1))
ufnCheckDarkhastFaktorMablaghConstraint:
returns bit
as
begin
declare @SumMablagh float
declare @Mablagh float
select @SumMablagh = isnull(sum(Mablagh), 0)
from Treasury.DariaftPardakhtDarkhastFaktor
where DarkhastFaktor= @DarkhastFaktor
select @Mablagh = isnull(MablaghKhalesFaktor, 0)
from Sales.DarkhastFaktor
where DarkhastFaktor= @DarkhastFaktor
if @Mablagh - @SumMablagh < -1
return 0
return 1
end
Lösung
Überprüfen Einschränkungen werden für Löschvorgänge nicht durchgesetzt werden, finden Sie unter http: // msdn .microsoft.com / en-us / library / ms188258.aspx
CHECK-Einschränkungen werden nicht validiert während DELETE-Anweisungen. Deshalb, Ausführen von DELETE-Anweisungen für Tabellen mit bestimmten Arten von Kontroll Beschränkungen können unerwartete erzeugen Ergebnisse.
Bearbeiten - Ihre Frage auf Abhilfe zu beantworten, können Sie einen DELETE-Trigger verwenden, um ein Rollback, wenn Ihr Funktionsaufruf zeigt eine Invariante ist gebrochen
.Bearbeiten # 2 - @reticent, wenn Sie Hinzufügen von Zeilen dann der Funktion durch die Check-Einschränkung genannt in der Tat sollte die Zeilen sehen. Falls es nicht klappt, wäre Check-Einschränkungen nutzlos. Hier ist ein einfaches Beispiel, werden Sie feststellen, dass die ersten zwei Einsätze erfolgreich zu sein und die dritten nicht wie erwartet:
create table t1 (id int)
go
create function t1_validateSingleton ()
returns bit
as
begin
declare @ret bit
set @ret = 1
if exists (
select count(*)
from t1
group by id
having count(*) > 1
)
begin
set @ret = 0
end
return (@ret)
end
go
alter table t1
add constraint t1_singleton
check (dbo.t1_validateSingleton()=1)
go
insert t1 values (1)
insert t1 values (2)
insert t1 values (1)