Transaction avec Read Committed Niveau d'isolation et contraintes de table
-
06-09-2019 - |
Question
Est-ce que les contraintes de table exécutent dans la même transaction?
J'ai une transaction avec Lire niveau d'isolement Engagé qui insère des lignes dans une table. La table a une contrainte sur ce qui appelle une fonction qui à son tour sélectionne quelques lignes de la même table.
Il semble que la fonction fonctionne sans savoir quoi que ce soit au sujet de la transaction et la sélection dans la fonction retourne des lignes dans le tableau qui y avait avant l'opération.
Y at-il une solution de contournement ou suis-je manque quelque chose? Merci.
Voici les codes pour la transaction et la contrainte:
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
La solution
Les contraintes de vérification ne sont pas appliquées pour les opérations de suppression, consultez http: // msdn .microsoft.com / fr-fr / bibliothèque / ms188258.aspx
contraintes CHECK ne sont pas validées lors de déclarations SUPPR. Donc, exécution d'instructions SUPPRIMER sur les tables avec certains types de contrôle les contraintes peuvent produire inattendues résultats.
Modifier - pour répondre à votre question sur solution de contournement, vous pouvez utiliser un déclencheur de suppression pour revenir si votre appel de fonction affiche un invariant est cassé
.Edit # 2 - @reticent, si vous ajoutez des lignes puis la fonction appelée par la contrainte de vérification devrait en fait voir les lignes. Si elle n'a pas, les contraintes de contrôle seraient inutiles. Voici un exemple simple, vous constaterez que les 2 premiers inserts réussissent et le troisième tombe en panne comme prévu:
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)