所以,如果我們的連接斷開,我們正試圖安排一個數據庫返回到multi_user模式。 的工作方式如下,但與罪惡一樣醜陋。
首先,我們適當地做一些事情,:
create database RevertTest
go
use master
go
create table RevertLock (L int not null)
go
declare @rc int
declare @job_id uniqueidentifier
exec @rc = msdb..sp_add_job @job_name='RevertSingleUser',
@description='Revert the RevertTest database to multi_user mode',
@delete_level=3,
@job_id = @job_id OUTPUT
if @rc != 0 goto Failed
exec @rc = msdb..sp_add_jobstep @job_id = @job_id,
@step_name = 'Wait to revert',
@command = '
WHILE EXISTS (SELECT * FROM RevertLock)
WAITFOR DELAY ''00:00:01''
ALTER DATABASE RevertTest set multi_user
DROP TABLE RevertLock'
if @rc != 0 goto Failed
declare @nowish datetime
declare @StartDate int
declare @StartTime int
set @nowish = DATEADD(minute,30,GETDATE())
select @StartDate = DATEPART(year,@nowish) * 10000 + DATEPART(month,@nowish) * 100 + DATEPART(day,@nowish),
@StartTime = DATEPART(hour,@nowish) * 10000 + DATEPART(minute,@nowish) * 100 + DATEPART(second,@nowish)
exec @rc = msdb..sp_add_jobschedule @job_id = @job_id,
@name='Failsafe',
@freq_type=1,
@active_start_date = @StartDate,
@active_start_time = @StartTime
if @rc != 0 goto Failed
exec @rc = msdb..sp_add_jobserver @job_id = @job_id
if @rc != 0 goto Failed
print 'Good to go!'
goto Fin
Failed:
print 'No good - couldn''t establish rollback plan'
Fin:
基本上,我們創建了以後我們收拾工作。我們安排這項工作在半小時內開始運行,但這只是爲了保護我們免受小規模的比賽。
我們現在運行我們的實際腳本做到這一點,以我們想要的工作:
use RevertTest
go
alter database RevertTest set single_user with rollback immediate
go
begin transaction
go
insert into master..RevertLock(L) values (1)
go
exec msdb..sp_start_job @job_name='RevertSingleUser'
go
WAITFOR DELAY '01:00:00'
如果您運行此腳本,你就可以觀察到該數據庫已經進入單用戶模式 - 最後的WAITFOR DELAY
只是爲了模擬我們「做工作」 - 無論您希望在數據庫中執行單個用戶模式的操作。如果您停止運行該查詢和斷開此查詢窗口,在一秒鐘內您應該看到數據庫已返回到multi_user
模式。
要成功完成腳本,只需從RevertLock
表中刪除最後一個任務(在COMMIT
之前)即可。與斷開連接一樣,恢復作業將負責將DB切換回multi_user
,然後自行清理。
的工作實際上是略有欺騙性。它實際上不會在循環中檢查主表中的表 - 因爲您的事務由於INSERT
而具有排它鎖。它會坐下來耐心地等待獲得合適的鎖定,這隻有在您的交易提交或回滾時纔會發生。
詢問如何能夠*完全*錯誤已告訴你不可能的事情似乎不是很明智。如果您的實際目標是您最終陳述的內容,則可能存在其他可行的策略 - 將數據庫作爲某種形式的故障安全恢復到多用戶模式。 (例如,在開始工作之前設置一個適當的工作計劃以更改數據庫) –
@Damien_The_Unbeliever我顯然是在尋找圍繞 –