【发布时间】:2012-03-15 02:51:55
【问题描述】:
我有一个需要设置保存点的存储过程,以便它可以在某些情况下撤消它所做的一切并将错误代码返回给调用者,或者接受/提交它并将成功返回给调用者。但是无论调用者是否已经开始交易,我都需要它来工作。该文档在这个主题上非常混乱。这是我认为可行的方法,但我不确定所有的后果。
问题是 - 这个Stored Procedure (SP) 被其他人调用。所以我不知道他们是否已经开始交易了......即使我要求用户开始交易才能使用我的SP,我仍然对Save Points的正确使用有疑问......
我的 SP 将测试交易是否正在进行,如果没有,则以BEGIN TRANSACTION 开头。如果事务已经在进行中,它将改为使用SAVE TRANSACTION MySavePointName 创建一个保存点,并保存我所做的事实。
然后如果我必须回滚我的更改,如果我之前做了一个BEGIN TRANSACTION,那么我会ROLLBACK TRANSACTION。如果我做了保存点,那么我会ROLLBACK TRANSACTION MySavePointName。这种情况似乎效果很好。
这是我有点困惑的地方——如果我想保留我已经完成的工作,如果我开始交易,我将执行COMMIT TRANSACTION。但是如果我创建了一个保存点呢?我尝试了COMMIT TRANSACTION MySavePointName,但随后调用者尝试提交其事务并收到错误:
COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION。
所以我想知道 - 可以回滚保存点(有效:ROLLBACK TRANSACTION MySavePointName 不会回滚调用者的事务)。但也许永远不需要“提交”它?它只是停留在那里,以防您需要回滚到它,但是一旦原始事务被提交(或回滚)就消失了?
如果有“更好”的方式来“嵌套”交易,也请说明一下。我还没有想出如何与BEGIN TRANSACTION 嵌套,但只能回滚或提交我的内部事务。似乎ROLLBACK 将始终回滚到顶部事务,而COMMIT 只是减少@@trancount。
【问题讨论】:
-
您的发现可能值得作为答案发布。
-
@Andriy 好的,这就是我所做的 - 删除了我的编辑并将其用作答案。谢谢。
标签: sql-server transactions nested-transactions