0

問題SQL服務器 - 單用戶模式 ​​- 依然存在,用戶

有沒有一種方法,把一個數據庫進入單用戶模式時,指定用戶(在我的情況下,它是當前用戶),和以確保即使在用戶斷開連接之後,單個會話仍保留給該定義的用戶;即它真的是單用戶而不是單用戶?

背景

給予一定的背景下...

我們有一些腳本來刷新我們的測試環境中的數據。 最近一次失敗,顯示錯誤,指出運行腳本的用戶帳戶無權訪問數據庫。 在調查中,用戶是數據庫上的系統管理員;所以這顯然不是真的。 但是,我發現該腳本將數據庫置入Single User模式。 查看數據庫上的活動會話時,我可以看到單個用戶與預期的帳戶不同(而是另一個屬於系統的間歇性輪詢此數據庫的服務帳戶)。 我的假設是出現以下情況:

  • 腳本運行作爲用戶A
  • 腳本把DB到單用戶模式
  • 腳本執行一些查詢/ IES
  • 腳本關閉,同時做一些其他的任務,當前連接
  • UserB嘗試連接到數據庫; UserA會話現在關閉成功
  • UserB的會話保持打開狀態(因爲UserB是具有連接池的服務,即使操作完成後會話保持打開狀態)。
  • UserA嘗試重新連接到DB;訪問被拒絕,因爲UserB採取單一會話

存在各種可能的解決方案。

  • 重寫劇本,以保持持久連接(可能很多的努力特別是我不熟悉的代碼)
  • 禁用所有服務,這可能會嘗試連接間歇性(有點違背了使用一個點單用戶模式/還有很多額外的努力來調查所有可能連接的賬戶,並保持這一點)
  • 添加一個捕獲腳本來殺死競爭的SPIDs,從而回收單用戶會話(我不像殺死SPIDs,因爲這會影響交易完整性)
  • 使用魔法(即查看接受的問題答案; h opefully)

更新

代碼使用PowerShell的Invoke-SqlCmd,其創建和刪除每一個命令運行連接;因此,只要數據庫處於單用戶模式,連接就會丟失。 我查看了這個命令參數,看看是否有連接池/持久連接的選項,但最接近的我可以找到的是DedicatedAdministratorConnection,儘管我最初的希望似乎我應該避開(http://www.brentozar.com/archive/2011/08/dedicated-admin-connection-why-want-when-need-how-tell-whos-using/)。

回答

0

對不起,沒有魔法。沒有你需要的本地解決方案。 SQL Server確保設置單用戶模式的會話是存活的會話。一旦該會話終止(用戶斷開連接,網絡中斷等),「插槽」現在可用於任何其他連接,包括某些後臺工作線程或SSMS對象瀏覽器。除救援行動以外,DAC不是一個好主意。

您可以使用sqlcmd運行腳本或從PS調用腳本文件(invoke-sqlcmd -inputfile「c:\ mysqlfile.sql」-serverinstance「servername \ serverinstance」-database「mydatabase」),以便在一個會話而不是來自PS的單個會話。

阻止用戶連接到DB(觸發器,安全等等)還有很多其他方法,但這些方法通常有風險,因爲您需要非常小心地執行塊並確保塊安全並在完成後正確刪除。這是不平凡的,因爲您需要考慮連接丟失或實例丟失以及恢復或恢復後如何處理狀態。得到真正的混亂,真正快速,所以仔細踩。