0

我最近尝试了 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 代码之后,我们刚刚复制的组合数据库中的所有数据突然消失了。我首先假设它还没有真正完成,所以“立即回滚”听起来像是对我的事务执行了回滚..

但为什么?事务不是已经提交了吗?

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

我的连接到底发生了什么?

4

3 回答 3

1

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

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

现在您需要将数据库恢复到一致的状态,即数据复制之前的状态。使用您在数据移动之前进行的备份(您确实进行了备份,对吗?)。为了获得额外的荣誉,请确保您的脚本是幂等的并且在半更新的数据库上正常工作。

于 2012-06-11T08:07:43.327 回答
0

立即回滚:

所有未完成的事务将被回滚,并且与数据库的任何其他连接将立即断开。

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

参考:更改数据库

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

于 2012-06-11T07:23:30.867 回答
0

我会仔细检查以确保没有未完成的交易。要么浏览文件并计算BEGIN TRANSACTIONvsCOMMIT TRANSACTION行数,要么在文件末尾添加一条语句以SELECT @@TRANCOUNT确保没有剩余的未处理事务。

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

于 2012-06-11T07:43:50.387 回答