SQL事务的实际成本是多少?

End*_*der 3 sql sql-server ado.net

这需要一些背景知识.我正在创建一个Web应用程序(带有SQL Server后端的ASP.NET/VB.NET),它将接受一个应用程序来接收资金,这个表单有三个人的联系信息字段.因为所有三个人(姓名,电子邮件,电话)的信息都相同,所以我选择将联系信息存储在与应用程序分开的表中.在应用程序表中,这三个联系人中的每一个都有一个ID字段,指向联系人表中的联系人.

然而,这在我做CRUD的过程中提出了一个有趣的问题.我可以想到在一个SQL事务中为应用程序和所有三个联系人创建,更新和检索信息的唯一方法需要非常复杂的存储过程.换句话说,通过多个事务检索此信息会更简单(对我来说).但是,由于这些信息永远不需要独立,我总是会做多个事务来获取一个应用程序的信息.

所以我的问题:

  1. 这种设计是否过度杀伤?每个应用程序永远不会有超过三个联系人,并且必须有三个.通过将此信息删除到单独的表格,我是否过于复杂?
  2. 执行多个SQL事务与编写复杂存储过程并且只需要一个事务的实际成本是多少?
  3. 一般来说,使用ADO.NET对Web应用程序进行SQL事务的成本是多少?

感谢您对这个冗长的解释感到满意.

*编辑*

在阅读了一些回复之后,看来我使用"交易"一词是错误的.我真正好奇的是在单个连接上执行多个查询的成本与执行一个查询相比.很抱歉对于这个误会.

Rem*_*anu 8

需要事务来将数据库从一个一致状态移动到另一个一致状态.这里的"一致"适用于数据库的应用程序视图.典型的例子是两个账户之间的汇款:您必须借记一个账户并贷记另一个账户.在这两个操作之间,数据库是不一致的,有一些钱已经"消失"(从一个账户中扣除的金额无处可去).但在事务结束时,数据库再次保持一致.您需要一个事务来跨越这两个操作,以保护读者不要查看不一致的数据库,并在发生崩溃时确保数据库一致.

您说为了在单个事务中处理逻辑中的多个项目,您需要复杂的过程.事实并非如此,事务范围与请求范围正交:客户端可以启动事务,通过在3个调用中调用3个过程来执行3个操作,然后提交事务.它要求所有的操作在一个单一的存储过程来完成.

因此交易应该不会引起显著的程序开销.事实上,一个程序将无视交易.在事务内部调用时以及在没有事务的情况下调用时,编写良好的过程应该正常运行.有关在存在事务异常时行为正常的过程,请参阅模板的异常处理和嵌套事务.

最后,交易的实际成本是多少?事务写入数据(读取实际上不需要事务),因此它们锁定修改的行.尝试读取这些被阻塞的行时,读取通常会阻塞,然后事务越长,锁定行的时间越长,阻塞的读取越多.但是有一个非常简单的解决方案:快照读取.快照读取真的是一个神奇的小精灵粉尘,它们允许应用程序不受阻塞行的阻碍,因为读者总是可以在阻止行的更新之前读取行版本.请参阅使用基于行版本控制的隔离级别.

所以结论很简单:交易没有成本.仅仅因为没有替代交易.不是'X比Y慢'的问题,是'X是唯一正确的选择'的问题.

更新

您的编辑后:成本啊有多个请求对一个请求能够显著.到服务器的往返(即,在开放连接上发出请求)具有固定成本.如果您进行多次往返,则需要在每次请求时支付此固定费用.如果您使用多个过程调用执行一个请求,则此固定成本仅支付一次.在非常热的系统上,这种差异是可测量的并且具有整体性能的成本.但我说的是真正热门的系统,就像每秒数千个请求一样.解决方案通常不会使过程复杂化,而是在一个请求中发出多个过程调用:

SqlCommand cmd = new SqlCommand(@"
exec usp_firstProc @arg1, @arg2;
exec usp_secondProc @arg2, @arg3;
exec usp_thirdProc @arg1, @arg3;", connection);
cmd.Parameters.Add("@arg1", someValue);
...
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

但我必须说,除非你的工作量非常热,否则不需要这个解决方案.作为一个封套的规则,对于1000个以下的请求/秒,我会认为明确代码的好处超过了性能优势.

如果您必须为每个请求打开一个新连接,那么有一点不同.登录握手真的很贵,可以测量几百毫秒.但解决方案很简单:连接池(在ADO.Net中默认启用)并且不会丢弃应用程序prematurel中的连接,保持连接并重复使用它直到整个工作单元完成.