2009-05-27 81 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