1

我一直在尝试在 SQL Server 和 C# 中使用事务。考虑一个将一行插入三列表的存储过程

alter proc spInsertItem
 @itemId int
,@itemDescription varchar(50)
,@itemCost decimal
as
begin
    if(@itemCost < 0)
        begin
            raiserror('cost cannot be less than 0',16,1)
        end

    else
        begin
            begin try
                begin tran
                    insert into Items(itemid, [description],itemCost)
                    values (@itemid, @itemdescription,@itemCost)
                commit tran
            end try
        begin catch
            rollback tran
                select   ERROR_LINE()as errorLine
                        ,ERROR_MESSAGE() as errorMessage
                        ,ERROR_STATE() as errorState
                        ,ERROR_PROCEDURE() as errorProcedure
                        ,ERROR_NUMBER() as errorNumber
        end catch
    end
end 

对比

create proc spInsertItem2
 @itemid int
,@itemDescription varchar(50)
,@itemCost decimal
as
begin
insert into Items(ItemId,[Description],ItemCost)
values (@itemid, @itemDescription,@itemCost)
end

在第一个示例中,通知用户他们无法输入低于 0 的项目成本,其余部分非常不言自明。这让我想到,如果你要禁止某些值,你应该需要一个检查约束,所以我添加了以下约束

alter table items
add constraint chkItemCost 
check (ItemCost > 0)

现在这两个存储过程在代码中的功能相同,并且 SQL 更短,在我看来,在第二个更短的版本中更易于阅读。当然,这是一个非常基本的示例,但在我看来,如果您try/catch在调用存储过程时看到 in 代码,则可以确定数据库没有处于不一致状态。那么,我错过了什么不应该依赖 C# 来创建事务?

4

1 回答 1

0

这通常是一个设计决定;应用程序的逻辑所在的位置。如果您决定将业务逻辑集中在应用程序代码中,那么对于涉及多次访问数据库的每个原子应用程序逻辑,您需要使用 C# 中的事务来包装该逻辑。

然而,如果您在 SP 的帮助下将业务逻辑存储在数据库中,则不需要 C# 中的事务。

一个常见的场景是:

  1. 您在数据库中创建一条或多条记录。
  2. 您在 C# 中对此数据进行一些后期处理。
  3. 您使用刚刚处理的数据更新另一个表。

要求是,如果第 2 步或第 3 步失败,则应回滚第 1 步(创建的记录)。为此,您需要交易。您可能会争辩说您可以将所有三个步骤都放在一个 SP 中并用事务包装它;这应该是可能的,通常是您将应用程序逻辑放在哪里的偏好问题。

于 2013-08-12T17:28:41.147 回答