我注意到我的生产SQL Server上有很多数据库连接处于打开状态,有些已经很长时间了。其中许多都有一个公开的交易。如查询中所示:
select * from sysprocesses where open_tran>0
他们处于status =“sleeping”,cmd =“AWAITING COMMAND”。
使用NHIBERNATE打开连接,如下所示:
For<ISessionFactory>().Singleton()
.Use(() => DataContext.GetSessionFactory());
For<ISession>().Transient()
.Use(context => context.GetInstance<ISessionFactory>().OpenSession());
某些会话使用交易范围: _transactionScope = new TransactionScope();
有些人创建了一个交易:
_uncommittedTransaction = SessionUncommittedWrapper.Session.BeginTransaction(IsolationLevel.ReadUncommitted);
事务和/或transactionScope随后处理。
为什么连接仍然打开?如果什么都没有被阻止,这是一个问题吗?
答案 0 :(得分:3)
他们处于状态=&#34;睡觉&#34;,cmd =&#34; AWAITING COMMAND&#34;。
当您在sysprocesses中看到状态为sleep的行时,这意味着此连接处于活动状态,但未被使用。这也是由于SQLServer使用connection Pooling mechanism而发生的。
等待命令可以通过以下示例解释..
第1节:开始此交易
begin tran
update t
set t1.a=<<some input from user>>--waiting
where t1.a=oldvalue
commit
现在,当您检查sys.processes / session DMV中session1的状态时,您可以看到它正在等待命令..因为,您没有提交它。
等待命令的另一个原因可能是当您启动事务并等待
之类的用户输入时Create proc myProc
As
Begin tran
Update authors ….
Waitfor delay ’10:00:00’ — time out will occur here (simulates long workload)
rollback
go
这是一个问题,如果什么都没有被阻止?
只要你看到,没有任何东西被阻挡,睡觉和会话没有任何锁定而且你没有看到任何公开的交易,你不必担心。这可以通过{{3来解释}} ..
问题通常出现在持有锁并且其状态正在休眠/等待命令的会话周围。如果客户端具有打开的事务并且客户端未提交提交或回滚命令,则状态为休眠/等待命令。我经常看到一个超时的程序。
RowId()
当从具有30秒查询超时的客户端运行时,事务将保持打开状态,因为客户端表示它想要“取消执行”并且不进行进一步处理。
要在这种情况下获得自动回滚,必须启用事务中止。您现在有一个带有SPID休眠/等待命令的打开事务。 这种情况可能是由许多其他变体引起的,但它始终是SQL Server正在等待来自客户端的下一个命令的情况
答案 1 :(得分:1)