【问题标题】:Does Sql make implicit rollback if my rollback timeout?如果我的回滚超时,Sql 是否会进行隐式回滚?
【发布时间】:2009-06-04 08:14:49
【问题描述】:

我有一个 dotnet 应用程序,它以事务方式执行一组插入、更新、删除语句

代码是这样的

try
{
mytrans = mycon.begintransaction();
//execute sql statements
mytrans.commit();
}
catch(Exception)
{
mytrans.rollback();
}

问题是有时我们在回滚时遇到超时异常,我发现数据库大小(mdf文件)增加了!!! 那么这是否意味着Sql不会进行隐式回滚?如果是这样,我怎样才能从这个错误中恢复并进入原始状态???

【问题讨论】:

    标签: sql-server-2008 timeout rollback


    【解决方案1】:

    事务的基本概念要求未提交的事务不影响数据库的状态。

    文件大小没有任何意义。 RDBMS 数据结构比简单地在文件中添加一行要复杂得多 - 它们包括日志和索引,因此文件可以完全独立于数据库中的数据量而增长和缩小。

    【讨论】:

    • 也就是说,没有提交的事务会被隐式回滚,不是吗?如果是这样,回滚方法的目的是什么
    • 是的,当数据库连接关闭时(可能是超时),未提交的事务会隐式回滚。回滚方法的重点是让您的程序对此进行控制,因为可能存在回滚不是由技术问题而是由程序逻辑引起的情况,即程序启动事务,执行一些操作,然后决定回滚事务并使用相同的数据库连接执行其他操作c。
    • 好的,但是我的逻辑是首先我将当前表转移到历史表,然后在转移过程中进行一些处理,我遇到了主键违规异常,所以程序试图回滚并发生超时异常,之后我发现特定历史表中存在冗余值!!!这意味着 sql 无法回滚(我认为是这样)
    • 你如何“拉屎”?通过移动单个行,还是对整个表执行某些操作?后者将是非常不寻常的,并且可能会暴露事务处理中的错误。或者它可能是某种自动提交发生。
    • 只需从当前表插入到历史表中,然后截断当前表
    【解决方案2】:

    任何可能已经执行的 SQL 都不会被提交。如果您的回滚由于某种原因超时不会导致提交。因此,DB 最终会意识到它已经变成了梨形并丢弃了这些更改。

    MDF 大小的增加并不表示事务已提交。然而,交易的结果需要放在某个地方。事务的提交应该需要数据库中可能的最小更改。因此,可能会分配页面并写入数据,然后在提交时只调整指向所有正确位置的其他几个位。

    如果有回滚,最后几位不会被调整,那些分配的页面只是成为空闲页面以用于其他事情。你不能指望数据库再次缩小。

    【讨论】:

      【解决方案3】:

      分页可以在回滚中存活:

      http://sqlfool.com/2009/04/page-splitting-rollbacks/

      【讨论】:

        【解决方案4】:

        一旦开始回滚,它就必须完成。无论您是否仍然连接,SQL Server 仍然会完成回滚。未能完成回滚会导致您的数据库事务性损坏并需要恢复。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-17
          • 1970-01-01
          相关资源
          最近更新 更多