我说的对吗?从性能角度来看,与代码相比,sql事务在存储过程中更好吗?
目前,我大多数事务都在存储过程中使用,但有时我会使用代码进行更复杂的例程-尽可能将其保持最小。
只是有一个复杂的例程需要太多“变量”,用C#编写SQL事务比使用SQL Server更容易。这是代码可读性和性能之间的微妙平衡。
有什么想法吗?
我说的对吗?从性能角度来看,与代码相比,sql事务在存储过程中更好吗?
目前,我大多数事务都在存储过程中使用,但有时我会使用代码进行更复杂的例程-尽可能将其保持最小。
只是有一个复杂的例程需要太多“变量”,用C#编写SQL事务比使用SQL Server更容易。这是代码可读性和性能之间的微妙平衡。
有什么想法吗?
SqlTransaction
的开销可能比一个TransactionScope
要小,特别是当TransactionScope
决定需要与DTC纠缠在一起时。但我不会期望SqlTransaction
和BEGIN TRAN
之间有很大的区别,除了额外的往返。然而,TransactionScope
仍然很快,并且是封装多个操作在事务中最方便的选项,因为环境事务不需要每次手动关联命令。
也许一个更好(并且更重要)的因素是隔离级别isolation-level。 TransactionScope
默认为最高级别(可序列化)。较低的隔离级别允许更少的阻塞(但存在非可重复读等风险)。我IRC TSQL事务默认为较低的级别之一。但是所有3个选项的隔离级别都可以进行调整。
我推荐使用TransactionScope
。根据Marc的建议,对于我所想到的大多数常见用途,可以在TransactionScope
上使用工厂方法将隔离级别降低到READ COMMITTED
。
请注意,您可以同时使用SQL事务和TransactionScope
- SQL的BEGIN TRAN
/ COMMIT TRAN
对TransactionScope
的影响很小(除了增加/减少@@TRANCOUNT
)- 这样,如果您需要从其他地方调用相同的SQL Sproc,例如从adhoc查询中,您仍将获得事务的好处。
我认为TransactionScope
的好处是,如果您确实需要执行2阶段提交(例如,多个数据库,队列或其他XA事务),它将为您管理DTC。而且,对于SQL 2005及更高版本,它与轻量级事务管理器一起使用,因此如果所有访问都针对一个数据库,每次只使用一个连接,则不需要DTC。
代码(阅读 c#)中的事务管理是一种选项,用于管理跨多个数据源或系统的事务。对于单个数据库的事务管理,服务器端的管理始终更简单。但如果您认为代码可能需要适应涉及多个数据源的情况,请在代码级别保留事务。
我相信存储过程会有更好的性能。
如果你的意思是在C#中编写SQL事务并使用ADO.Net或类似工具来执行它们,那么它们可能不太高效,因为SQL将缓存存储过程的查询计划(虽然现在Entity Framework也是如此,但我认为仍然不如存储过程快),所以你应该反过来做 - 在SQL中编写复杂的存储过程以获得缓存优势(如果只是这么简单就好了...)
这取决于应用程序。
但我会说,在大多数情况下,最好在数据库中具有逻辑。在数据库中具有业务逻辑也非常有优势,因为即使您拥有WinForms版本和Web版本等不同版本,它也将是相同的。
但是,如果您谈论SQL中的CLR,则负面影响是,DBA更难找到任何错误或性能问题。