【问题标题】:Transaction with Read Committed Isolation Level and Table Constraints具有已提交读隔离级别和表约束的事务
【发布时间】:2009-05-27 13:05:44
【问题描述】:

表约束是否在同一个事务中执行?

我有一个已提交读隔离级别的事务,它在表中插入一些行。该表有一个约束,它调用一个函数,该函数依次从同一个表中选择一些行。

看起来函数在不了解事务的情况下运行,并且函数中的选择返回了事务之前表中的行。

有解决方法还是我遗漏了什么?谢谢。

这里是交易和约束的代码:

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

【问题讨论】:

    标签: sql-server transactions constraints isolation-level


    【解决方案1】:

    检查约束不适用于删除操作,请参阅http://msdn.microsoft.com/en-us/library/ms188258.aspx

    CHECK 约束未验证 在 DELETE 语句期间。所以, 对表执行 DELETE 语句 某些类型的支票 约束可能会产生意外 结果。

    编辑 - 要回答您有关解决方法的问题,如果您的函数调用显示不变量已损坏,您可以使用删除触发器回滚。

    编辑#2 - @reticent,如果你要添加行,那么检查约束调用的函数实际上应该看到行。如果没有,检查约束将毫无用处。下面是一个简单的例子,你会发现前2次插入成功,第三次按预期失败:

    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)
    

    【讨论】:

    • 我不想删除行。我只希望函数(由检查约束调用)能够看到我在当前事务中插入的行。
    • @reticent - 如果你正在插入,那么函数应该会看到行。请参阅我在其中编辑的示例。
    猜你喜欢
    • 1970-01-01
    • 2020-08-18
    • 2014-01-03
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多