应用设计——ServiceStack; OrmLite.MySql;功能; IDb连接;石英

Application design - ServiceStack; OrmLite.MySql; Funq; IDbConnection; Quartz

我们有一个 ServiceStack 服务 (API),它提供使用 [= 托管的 HTTP 端点26=]AppSelfHostBase。 这些服务随后使用 ServiceStack.OrmLite.MySql 查询数据库。所有方法都是使用 async / await pattern 实现的。数据库连接手动注册到具有请求重用范围的 Funq,并注入到基础 DAL class.

的 属性

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

“There is already an open DataReader associated with this Connection which must be closed first.”

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


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


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

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

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