可以在 SQL Server 中没有相应的 BEGIN TRAN 的情况下提交事务吗?
Posted
技术标签:
【中文标题】可以在 SQL Server 中没有相应的 BEGIN TRAN 的情况下提交事务吗?【英文标题】:Can a Transaction be Committed Without a Corresponding BEGIN TRAN in SQL Server? 【发布时间】:2019-01-03 16:58:53 【问题描述】:在 SQL Server 中,我们有一系列存储过程来处理从包装过程调用的数据。在此过程结束时,它会执行一个过程来汇总数据并将其转储到单独数据库中的表中。数据在客户查看时不断变化,因此我们使用 (nolock) 提示来防止锁定表。我知道这不是最佳实践,但不幸的是我没有创建这个过程,我必须忍受它。正如我确信您所期望的那样,我遇到的问题是有时它会将脏数据插入汇总表中。当没有 BEGIN TRAN 时,有没有办法在执行我的程序之前提交我之前的程序中的新记录?另一个注意事项:我不能使用 BEGIN TRAN。
【问题讨论】:
如果您从脏读中提取数据并且不想插入到另一个表中,解决方案是停止使用 nolock。 如果你不想脏读,不要使用NOLOCK
。期间。
使用NoLock
不仅不是最佳实践,而且会完全损害数据的完整性,因为双读和脏读非常普遍。
对于这里关于 NOLOCK 的所有建议的一些很好的阅读,这里有一篇很好的文章(我有点惊讶@SeanLange 没有在他的评论中链接到)。 Bad habits : Putting NOLOCK everywhere
我正在阅读不良习惯文章,谢谢!
【参考方案1】:
我也会删除 NOLOCK,因为它在这种高度并发的场景中特别危险。
如果你真的不能使用 BEGIN TRAN,那么我认为你只需要删除 NOLOCK 并让 SQL Server 处理事情,这通常是一个好主意。 专注于调整所有涉及的进程中的 SQL,使其尽可能快,并且至少可以最大限度地减少阻塞。
如果可以,我建议让每个存储过程使用自己的事务 BEGIN TRANSACTION 和 COMMIT 将数据插入“中间”表。如果您出于任何原因希望它们回滚,我想您应该考虑传递一个标志,以便父过程可以避免任何进一步的处理。您会希望对这些语句进行很好的调整,以使它们锁定的时间不会超过需要的时间,因此正如其他人所建议的那样,请查看索引。
【讨论】:
以上是关于可以在 SQL Server 中没有相应的 BEGIN TRAN 的情况下提交事务吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥安装的SQL SERVER 2008中SQL SERVER 服务只有1个
SQL Server:如果左连接没有结果,则返回占位符/文本[重复]