我们有一个ASP.NET API网站,它使用NHibernate连接到SQL Server。
我们遇到的问题是,全天逐渐地,SQL服务器的连接数量逐渐增加,并且有许多连接似乎没有返回到池中。通过这个,我的意思是,如果我运行以下查询:
select * from master..sysprocesses s where datediff(minute, s.last_batch, getdate())>10
返回的行数不断攀升。 API中的任何内容都不需要花费10分钟才能完成。并且 hours 之前有连接。
这是另一个线索:所有这些行的open_tran
列的值为1.所以在我看来,在API调用中的某个地方,我们正在创建一个事务边界,并且该事务永远不会存在关闭。也许DTC可能参与其中(我们有时会在通话中连接到多个数据库)。
问题是,我不知道如何进一步解决这个问题。我试过在流氓spid上运行DBCC INPUTBUFFER
,并且它们之间没有任何一致。
可能导致此行为的一些反模式/其他可能原因是什么?
更新:以下是如何创建数据库连接。我们使用StructureMap进行依赖注入。我们在每个工作单元上创建两个DB连接:一个用于常规读/写访问的“普通”连接,以及一个在“ReadUncommitted”访问的事务中运行的“未提交”连接(我们在读取时遇到表锁定问题)来自大表)。
以下是DI Registry的代码:
For<ISession>().Transient().Use(context => context.GetInstance<ISessionFactory>().OpenSession());
For<ISessionUncommittedWrapper>().Transient().Use(context => new SessionUncommittedWrapper { Session = context.GetInstance<ISessionFactory>().OpenSession() });
然后,在工作单元中间件中,我们创建了一个UnitOfWork
(当然包含using
块),其中包含ISession
和ISessionUncommittedWrapper
个构造函数。在Begin()
方法中,我们有:
_uncommittedTransaction = SessionUncommittedWrapper.Session.BeginTransaction(IsolationLevel.ReadUncommitted);
在ISession
的{{1}}方法中被处置(以及ISessionUncommittedWrapper
和UnitOfWork
)。
答案 0 :(得分:0)
我最终找到了问题。
我发现问题的方法是创建一个跟踪<div id="div-l" class="single-stack"> </div>
<div id="div-m" class="single-stack"> </div>
<div id="div-r1" class="double-stack"> </div>
<div id="div-r2" class="double-stack"> </div>
s的创建和处理的日志记录表,以及调用的端点的URI。通过查询所有未连接的连接,我发现在每个情况下没有处理连接的情况下,路径以&#34; / signalr&#34;开始。
Session
由于OWIN中间件主动创建了Sql连接,因此SignalR也在这样做,它本质上保持了事务的开放性!因此,使用SignalR登录的每个客户端都占用了两个Sql连接。
我做了相应的更改以从中间件中排除SignalR连接,现在我们没有更多的挂起Sql连接。