将SQl Server数据库脱机时连接会发生什么变化?

时间:2012-06-11 07:12:03

标签: sql-server database transactions

我最近尝试过2个数据库的大合并。我们将数据库2中的模式重新创建到数据库1中,并创建了一个脚本,将数据库2中的所有数据传输到数据库1中。此脚本运行大约需要35分钟,并使用以下内容进行事务处理:

BEGIN TRANSACTION
...
IF(@@error<>0)
    COMMIT TRANSACTION
ELSE
    ROLLBACK TRANSACTION

完整脚本有点敏感,但这里有一些具有相同结构的SQL:http://pastebin.com/GWJ3ZnkF

我们运行了脚本,所有数据都没有错误地传输。我们测试了使用新组合数据库运行的系统(删除了对旧数据库的访问权限)。

但作为最后一项任务,我们希望将旧数据库脱机以确保没有人使用该数据库。为此,我们使用了:

ALTER DATABASE <dbname> SET OFFLINE WITH ROLLBACK IMMEDIATE

这很糟糕。在这行SQL代码之后,我们刚刚复制的组合数据库中的所有数据突然消失了。我首先认为它没有真正完成所以“回滚立即”听起来像是在我的交易上执行了回滚..

但为什么呢?交易是否已全部承诺?

此外,我尝试再次运行相同的脚本几次,但每次尝试都没有复制数据,即使它说脚本成功了。我不知道为什么......它是否记得我的离线回滚?

我的关系真的发生了什么?

3 个答案:

答案 0 :(得分:1)

听起来你有一个未提交的待处理事务,你强迫它回滚,失去了一些工作。其余部分通过脚本的结构来解释。您的脚本不可能从头到尾只有一个事务。只回滚了最后一个事务,因此数据库现在处于一半被复制的状态。可能你的脚本会进行各种检查,这个中间状态会在&#39; ELSE&#39;上发送脚本。它没有做正确工作的分支(即显然什么都不做)。

没有发布确切的脚本,无论如何都是猜测。

现在您需要将数据库还原到一致状态,即数据复制之前的状态。使用您在数据移动之前所做的备份( 进行备份,对吧?)。要获得额外的功劳,请确保您的脚本为idempotent,并且可以在半更新的数据库上正常运行。

答案 1 :(得分:0)

  

立即使用ROLLBACK:

     

将回滚所有未完成的交易以及任何其他交易   与数据库的连接将是   立即断开连接。

听起来有人混淆了2个数据库,或者有未完成的交易?....你能发布整个脚本吗?

Ref: ALTER DATABASE

不仅要检查@@ERROR,还要检查@@TRANCOUNT

答案 2 :(得分:0)

我会仔细检查以确保没有未完成的交易。要么遍历该文件并计算BEGIN TRANSACTION vs COMMIT TRANSACTION行的数量,要么在SELECT @@TRANCOUNT的末尾添加一个语句,以确保没有剩余的已打开的事务。

如果您的数据已提交,则断开连接就不会丢失。