应该在存储过程之外还是在内部指定事务?

时间:2009-03-06 12:23:57

标签: .net sql sql-server stored-procedures isolation

我们可以在事务中包装对存储过程的调用,并指定隔离级别。

或者我们可以将事务放在存储过程中指定那里的隔离级别。

哪个更好?

6 个答案:

答案 0 :(得分:7)

您应该采用一致的方法。请注意,回滚存储过程中的事务将回滚任何嵌套事务范围,包括任何外部范围。

我建议您将交易保留在程序之外。这样,你就可以完全控制。

答案 1 :(得分:5)

在我看来,存储过程内部是最合适的位置。

良好事务设计的基本规则之一是尽可能缩短事务的生命周期,因此提交应在事务逻辑完成后立即进行。控制存储过程之外的事务将导致不必要地延长事务的寿命。

您还应该考虑在过程中定义事务还可以使代码更加清晰。否则,如果另一个编码器需要修改给定的存储过程,则它们必须依赖于调用者确实将事务包装在事务中的事实。在程序中包含事务明确定义了您的事务处理。

答案 2 :(得分:5)

正如FYI一样,Oracle不支持嵌套事务,如果您在外层开始事务然后调用一系列存储过程,那么发出提交的任何存储过程将提交整个事务到目前为止,而不仅仅是它所煽动的交易。因此,在使用C#

等语言调用时,您必须在stored-proc之外管理事务

为了比较,您可能会感兴趣。

答案 3 :(得分:4)

在数据库API的外层,或至少在外层。

如果你在每个存储过程中提交,那么你也可以打开自动提交,对以下存储过程进行映像

create_user_with_email_address
  calls -> create_user
  calls -> create_email_address

如果您在create_user / create_email_address中提交,则create_user_with_email_address不再是事务性的,如果create_email_address失败,则create_user已经提交,并且您的数据已损坏。

根据需要将交易置于高位以保持其中的所有内容。

答案 4 :(得分:2)

这取决于业务逻辑,如果SP是原子的,它应该实现自己的事务。如果不这样做,将来会冒错误代码的风险,而不会创建包装事务。所以在回答你的问题时,我认为交易应该进入SP。

当然没有什么可以阻止你做这两件事,原子SP实现他们自己的交易,而在该范围之外,其他更广泛的交易可能已经存在。

通常,在SP中创建使用事务时,您可能已经在事务范围内,在执行提交/回滚时必须为此实例编写代码。

答案 5 :(得分:1)

我们在Sproc中执行以下操作,因为如果我们只是回滚它会破坏外部SProcs中的事务计数,这可以向应用程序生成警告 - 如果它不期望/处理它可能会导致应用程序错误。

但是,此方法仅回滚“本地”事务,因此外部“调用者”必须适当地解释返回值;或者使用RAISERROR或类似的。

BEGIN TRANSACTION MySprocName_01
SAVE  TRANSACTION MySprocName_02
...
IF @ErrorFlag = 0
BEGIN
    COMMIT TRANSACTION MySprocName_01
END
ELSE
BEGIN
    ROLLBACK TRANSACTION MySprocName_02
    COMMIT TRANSACTION MySprocName_01
END