简体   繁体   English

具有提交承诺隔离级别和表约束的事务

[英]Transaction with Read Committed Isolation Level and Table Constraints

Does table constraints execute in the same transaction? 表约束是否在同一事务中执行?

I have a transaction with Read Committed isolation level which inserts some rows in a table. 我有一个读取提交隔离级别的事务,该事务在表中插入了一些行。 The table has a constraint on it that calls a function which in turn selects some rows from the same table. 该表具有约束,该约束调用一个函数,该函数又从同一表中选择一些行。

It looks like the function runs without knowing anything about the transaction and the select in the function returns rows in the table which were there prior to the transaction. 似乎该函数在运行时不了解任何事务,并且该函数中的select返回表中在事务之前存在的行。

Is there a workaround or am I missing anything? 是否有解决方法,或者我有什么遗漏? Thanks. 谢谢。

Here are the codes for the transaction and the constraint: 以下是交易和约束的代码:

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

Check constraints are not enforced for delete operations, see http://msdn.microsoft.com/en-us/library/ms188258.aspx 未对删除操作强制执行检查约束,请参阅http://msdn.microsoft.com/zh-cn/library/ms188258.aspx

CHECK constraints are not validated during DELETE statements. CHECK约束在DELETE语句期间未得到验证。 Therefore, executing DELETE statements on tables with certain types of check constraints may produce unexpected results. 因此,在具有某些类型的检查约束的表上执行DELETE语句可能会产生意外的结果。

Edit - to answer your question on workaround, you can use a delete trigger to roll back if your function call shows an invariant is broken. 编辑-要回答有关变通方法的问题,如果函数调用显示不变式已损坏,则可以使用删除触发器回滚。

Edit #2 - @reticent, if you are adding rows then the function called by the check constraint should in fact see the rows. 编辑#2-@reticent,如果要添加行,则检查约束调用的函数实际上应该看到行。 If it didn't, check constraints would be useless. 如果没有,检查约束将毫无用处。 Here is a simple example, you will find that the first 2 inserts succeed and the third fails as expected: 这是一个简单的示例,您会发现前两个插入成功,而第三个失败按预期进行:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM