【发布时间】:2013-08-12 17:18:15
【问题描述】:
我一直在尝试在 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,则可以确定数据库没有处于不一致状态。那么,我错过了什么不应该依赖 C# 来创建事务?
【问题讨论】:
-
仅供参考 - 编辑您的标题,因为您的真正意思是“.NET Transactions”
-
真正的用例是更长的过程,特别是如果您需要使用显式事务(即从表中删除记录然后插入新数据) - 您希望 try/catch 中止过程然后在 catch 中添加回滚。
-
@JNK 所以对于较小的“日常”类型的应用程序,即典型的更新、插入、删除,可能不需要在 SQL 中编写事务?
-
@JohnSaunders 正确,谢谢。
-
@wootscootinboogie 这取决于您是否打算从 .NET 代码之外的任何地方调用这些 proc。如果你这样做,那么我认为事务应该在 SQL 中,但我是 SQL 开发人员,所以我有偏见
标签: c# sql transactions