I use the Db property in ServiceStack to access my database, but from time to time I get the following error from IIS:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Stack trace:
[InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.] System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +6371713 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372046 System.Data.SqlClient.SqlConnection.Open() +300 ServiceStack.OrmLite.OrmLiteConnection.Open() +44 ServiceStack.OrmLite.OrmLiteConnectionFactory.OpenDbConnection() +132 ServiceStack.ServiceInterface.Service.get_Db() +68
I installed ReuseScope in the Configure method on ReuseScope.None , which should close the connection for each request, I suppose? What am I doing wrong here?
public override void Configure(Container container) { JsConfig.EmitCamelCaseNames = true;
ConfigureDb:
private static void ConfigureDb(Container container) { var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString; container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider)) .ReusedWithin(ReuseScope.None); using (var db = container.Resolve<IDbConnectionFactory>().Open()) {
Edit
After more detailed diagnostics, it seems to happen when I refresh the page several times when I call this service method:
public Warranty Get(Warranty request) { var warranty = new Warranty(); if (request.Id != default(int)) { warranty = Db.Id<Warranty>(request.Id); warranty.WarrantyOrder = ResolveService<WarrantyOrderService>().Get(new WarrantyOrder { WarrantyId = warranty.Id }); warranty.WarrantyStatus = ResolveService<WarrantyStatusService>().Get(new WarrantyStatus { Id = warranty.StatusId }); warranty.WarrantyNotes = ResolveService<WarrantyNoteService>().Get(new WarrantyNotes { WarrantyId = warranty.Id }); warranty.WarrantyDialogues = ResolveService<WarrantyDialogueService>().Get(new WarrantyDialogues { WarrantyId = warranty.Id }); warranty.WarrantyCredit = ResolveService<WarrantyCreditService>().Get(new WarrantyCredit { WarrantyId = warranty.Id }); warranty.WarrantyPhotos = ResolveService<WarrantyPhotoService>().Get(new WarrantyPhotos { WarrantyReference = warranty.WarrantyReference }); warranty.WarrantyReport = ResolveService<WarrantyReportService>().Get(new WarrantyReport { WarrantyId = warranty.Id }); } return warranty; }
I modified ConfigureDb according to @mythz answer below:
private static void ConfigureDb(Container container) { var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString; container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider)); }
The service must call other services to populate other objects on my Warranty object, I'm not sure how to improve this?