1

我们有一个ServiceStack服务 (API),它提供使用AppSelfHostBase托管的 HTTP 端点。这些服务稍后使用ServiceStack.OrmLite.MySql查询数据库。所有方法都使用async/await 模式实现。数据库连接手动注册到具有请求重用范围的 Funq,并注入到基 DAL 类的属性中。


当此服务仅由 HTTP 请求访问时,这一切都可以正常工作。我们有另一个调用此 API 的 Windows 服务。由于它们可以托管在同一台服务器上,我们实现了本地IRestClientAsync来包装服务调用,因此 API 服务方法可以加载到 Windows 服务,并更有效地访问(例如 1200 req/sec 与 400 req/sec )。这个 Windows 服务有很多线程同时运行。通过这样做,我们打破了请求生命周期并得到

“已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭它。”</p>

错误。我们尝试使用自定义连接提供程序手动处理此问题,使用ThreadLocalCallContext通过线程分离连接。这并不是一直有效。我们尝试通过调用OnBeginRequest(null);OnEndRequest();手动处理请求生命周期,但性能很差(接近 HTTP 调用),并且出现“打开 DataReader”错误。


我们正在使用选项,因为线程是从Quartz .NET作业RequestContext.UseThreadStatic实例化的。


管理数据库连接的最佳解决方案是什么?我们能否使当前的解决方案可靠地工作?

4

1 回答 1

0

我要做的第一件事就是不要费心将 Async API 与 MySql 一起使用,因为它不是真正的异步,因为它最终会在幕后创建新线程来伪造异步,这使得它比使用 Sync API 的效率更低。您也不能使用具有相同数据库连接的多个阅读器,这最终会引发此异常。

所以我首先会回到使用 MySql 的同步 API,如果它仍然是一个问题,请使用瞬态范围(即没有重用)而不是请求范围,并让数据库连接池完成它的工作。请求范围保持连接的时间更长,占用了不必要的资源。

于 2015-12-07T17:45:10.257 回答