问题
有没有办法在将数据库置于单用户模式时指定该用户(在我的情况下是当前用户),并确保即使在该用户断开连接后,单个会话仍为该定义的用户保留;也就是说,它是真正的单用户而不是单并发用户?
背景
给出一些背景...
我们有一些脚本可以在我们的测试环境中刷新数据。最近一个失败,错误指出运行脚本的用户帐户无权访问数据库。经调查,该用户是数据库的系统管理员;所以这显然不是真的。但是,我发现该脚本将数据库置于Single User
模式。查看数据库上的活动会话时,我可以看到单个用户与预期帐户不同(而是属于间歇性轮询该数据库的系统的另一个服务帐户)。我的假设是发生了以下情况:
- 脚本以 UserA 身份运行
- 脚本将 DB 置于单用户模式
- 脚本执行一些查询/ies
- 脚本在执行其他一些任务时关闭当前连接
- UserB 尝试连接数据库;成功,因为 UserA 会话现已关闭
- UserB 的会话保持打开状态(因为 UserB 是具有连接池的服务,即使在操作完成后会话保持打开状态)。
- UserA 尝试重新连接到 DB;访问被拒绝,因为 UserB 进行了单个会话
有各种可能的解决方案。
- 重写脚本以保持持久连接(可能需要付出很多努力,尤其是在我不熟悉代码的情况下)
- 禁用所有可能尝试间歇性连接的服务(有点破坏了使用单用户模式的意义/还有很多额外的努力来调查所有可能连接的帐户,并保持这一点)
- 在脚本中添加一个捕获以终止竞争的 SPID,从而回收单个用户会话(我不喜欢终止 SPID,因为这会影响事务完整性)
- 使用魔法(即看到这个问题的公认答案;希望如此)
更新
该代码使用 PowerShellInvoke-SqlCmd
为每个命令运行创建和删除连接;因此,一旦将数据库置于单用户模式,连接就会断开。我查看了这个命令参数,看看是否有用于池/持久连接的选项,但我能找到的最接近的是DedicatedAdministratorConnection
,我似乎应该避开(http://www.brentozar.com/archive/2011/ 08/dedicated-admin-connection-why-want-when-need-how-tell-whos-using/)尽管我最初抱有希望。