在所有查询中都有TRANSACTION

Ter*_*rry 6 sql transactions sql-server-2005

你认为对存储过程中的每个sql语句进行TRANSACTION是一个好习惯吗?即将在我的公司中优化这个遗留应用程序,我发现有一件事是每个存储过程都有BEGIN TRANSACTION.即使是简单的select和Update语句也有一个.如果一个人正在执行多个操作,即(多次插入或更新或删除),而不仅仅是一个操作插入或更新或删除,我认为拥有BEGIN TRANSACTION会更好.我可能错了,这就是我需要别人给我建议的原因.谢谢你的时间.

Pan*_*vos 5

这是完全没有必要的,因为每个 SQL 语句都是以原子方式执行的,即。就好像它已经在自己的事务中运行一样。事实上,打开不必要的事务会导致锁增加,甚至死锁。忘记将 COMMIT 与 BEGIN 匹配会使事务保持打开状态,只要与数据库的连接处于打开状态并干扰同一连接中的其他事务。

这样的编码几乎肯定意味着编写代码的人在数据库编程方面不是很有经验,并且肯定还有可能存在其他问题。


Mar*_*ith 3

我不知道不只对这些语句使用自动提交事务有什么好处。

在任何地方使用显式事务的可能缺点可能是它只会增加代码的混乱,因此不太容易看出何时使用显式事务来确保多个语句的正确性。

此外,除非小心谨慎(例如使用SET XACT_ABORT ON),否则它会增加事务保持打开状态并持有锁的风险。

此外,还有一个较小的性能影响,如@8kb 的答案所示。这说明了使用 Visual Studio Profiler 的另一种方式。

设置

(针对空表进行测试)

CREATE TABLE T (X INT)
Run Code Online (Sandbox Code Playgroud)

显式的

SET NOCOUNT ON

DECLARE @X INT

WHILE ( 1 = 1 )
  BEGIN
      BEGIN TRAN

      SELECT @X = X
      FROM   T

      COMMIT
  END
Run Code Online (Sandbox Code Playgroud)

显式的

自动提交

SET NOCOUNT ON

DECLARE @X INT

WHILE ( 1 = 1 )
  BEGIN
      SELECT @X = X
      FROM   T
  END 
Run Code Online (Sandbox Code Playgroud)

自动提交

它们最终都会花费时间在CMsqlXactImp::Begin和 上CMsqlXactImp::Commit,但对于显式事务的情况,它在这些方法中花费了显着更大比例的执行时间,因此做有用工作的时间更少。

+--------------------------------+----------+----------+
|                                | Auto     | Explicit |
+--------------------------------+----------+----------+
| CXStmtQuery::ErsqExecuteQuery  | 35.16%   | 25.06%   |
| CXStmtQuery::XretSchemaChanged | 20.71%   | 14.89%   |
| CMsqlXactImp::Begin            | 5.06%    | 13%      |
| CMsqlXactImp::Commit           | 12.41%   | 24.03%   |
+--------------------------------+----------+----------+
Run Code Online (Sandbox Code Playgroud)