2009-05-27 79 views
1

表限制是否在同一事务中执行?具有读提交隔离级别和表限制的事务

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

它看起来像函数在不知道事务的情况下运行,函数中的select返回表中事务之前有的行。

有没有解决办法,还是我缺少什么?谢谢。

这里是交易和约束代码:

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 

回答

3

检查约束不执行删除操作,见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) 
+0

我不想删除行。我只想让该函数(由检查约束调用)能够查看我在当前事务中插入的行。 – reticent 2009-05-30 06:01:02