2012-06-11 53 views
0

我最近嘗試了2個數據庫的大合併。我們重新從數據庫2架構到數據庫1並創建了一個腳本,從數據庫2傳輸所有數據到數據庫1.該腳本需要大約35分鐘運行,並具有與交易處理:將SQl服務器數據庫脫機時連接會發生什麼?

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

完整的腳本有點敏感,但這裏有一些SQL具有相同的結構:http://pastebin.com/GWJ3ZnkF

我們運行了腳本,所有數據都被無誤地傳輸了。我們測試了使用新的組合數據庫運行的系統(刪除了舊數據庫的訪問權限)。

但作爲最後一項任務,我們希望將舊數據庫脫機以確保沒有人使用該數據庫。要做到這一點,我們使用:

ALTER DATABASE <dbname> SET OFFLINE WITH ROLLBACK IMMEDIATE 

這很糟糕。在這行SQL代碼之後,我們剛剛複製的組合數據庫中的所有數據突然消失了。我第一次認爲它並沒有真正完成,所以「立即回滾」聽起來像是在我的交易中執行了回滾。

但是爲什麼?是不是事務已經提交?

此外,我嘗試再次運行相同的腳本幾次,但在每次嘗試後,即使它說腳本是成功的,沒有數據被複制。我不知道爲什麼......是否記得我的離線回滾?

我的關係真的發生了什麼?

回答

1

聽起來就像你有一個待定的事務沒有提交,你迫使它回滾,失去了一些工作。其餘的解釋是你的腳本是如何構建的。你的腳本不太可能從頭到尾只有一筆交易。只有最後一個事務被回滾,所以數據庫現在處於「半複製」狀態。可能你的腳本會進行各種檢查,並且這個中間狀態會在'ELSE'分支上發送腳本,在那裏它不會做正確的工作(即顯然什麼都不做)。

無論發佈確切的腳本,無論如何都是猜測。

現在您需要將數據庫恢復到一致狀態,即數據複製之前的狀態。在數據移動之前使用您備份的備份(您的做了備份,對吧?)。要獲得額外的功勞,請確保您的腳本是idempotent,並在更新過的數據庫上正常工作。

+0

+1好的建議。 –

+0

謝謝,我懷疑這將會接近我會得到的答案。是的。我做了一個備份,但數據庫爲2個非常活躍的Web系統提供服務,因此數據庫將老化(僅在維護意味着加載後的幾個小時)才能恢復,除非我們確實必須這樣做。我將不得不嘗試創建一個腳本來處理當前狀態下的腳本。 – Swippen

0

WITH ROLLBACK立即

所有未完成的交易將被回滾和任何其他 連接到數據庫將 立即斷開。

聽起來像某人得到了2個數據庫混淆,或者可能有一個傑出的交易?....你可以發佈你的整個腳本?

Ref: ALTER DATABASE

而不是隻檢查@@ERROR,檢查@@TRANCOUNT以及。

+0

它的一點點敏感它基本上只是選擇/插入:http://pastebin.com/GWJ3ZnkF數據庫在2個不同的鏈接服務器上。我能理解爲什麼它第一次回滾。但是,當舊的數據庫再次聯機並重試時,即使它說腳本成功執行,它也拒絕複製任何數據。 – Swippen

0

我會仔細檢查以確保沒有未完成的交易。請通過該文件並計算BEGIN TRANSACTIONCOMMIT TRANSACTION行的數目,或者在其末尾添加一條語句至SELECT @@TRANCOUNT以確保沒有未完成的事務。

如果您的數據已被提交,那麼斷開連接將不會丟失它。

+0

傑出的交易聽起來像是影響重新運行的罪魁禍首。 –

+0

我只有一個開始和承諾,我已在問題中發佈。但是我可能有其他與合併無關的連接,我想強制關閉。他們會影響合併嗎?我會檢查@@ Transcount – Swippen

相關問題