Thanks, Valerie. Yes, we are caching our configuration but you're making me think. What we aren't doing (and I don't yet know how I could) is caching the mappings and creating the factories from whatever that might be. I'll have to start exploring to see if that is feasible....
On Wednesday, May 29, 2013 10:03:35 AM UTC-5, Valeriu Caraulean wrote: > > As a guess, have you tried to reuse the Configuration object? > If only connection string or database name changes, you can cache the > Configuration and re-use it. It’s one of the most expensive operations when > bootstrapping NHibernate... > > Valeriu > > *From:* Kerry <javascript:> > *Sent:* Wednesday, May 29, 2013 3:48 PM > *To:* [email protected] <javascript:> > *Subject:* [nhusers] Bootstrapping with multiple Session Factories > > We have a need in our app to support multiple "connections" to different > databases, with each connection supporting the same set of mappings. We > have a huge number of mappings (this is a decade-old legacy application), > and each connection and database has the same schema. We recently added a > feature to the application that allows a user on one connection to view > data on all of the other connections, which requires having all of the > connections available at the time of the request. > > Bootstrapping a single connection can take up to 20 seconds over a slow > wire. When one of our customers tried to view data on 7 connections, the > application (unsurprisingly) timed out. To address this, we are taking a > two-pronged approach: > > 1. bootstrap all connections prior to login of the first user (at > app_start); and > 2. at bootstrap, create the session factories for each connection in a > multi-threaded environment to reduce the timeout problem. > > > The second approach is proving to be problematic. When calling > BuildSessionFactory in a multi-threaded environment, the logs show that the > factories are being constructed serially. (i.e. I spin off the threads at > time A, and they come back at times B, B+10, B+20, B+30, etc). Another > developer reporting setting up an integration environment to test this, and > received a duplicate key exception from within NHIbernate. I have not yet > had time to review that error or his code, but it points to something > problematic with using nHibernate in a multi-threaded environment. > > Would somebody mind taking a look at the following code and commenting on > our approach? Thanks very much. > > > public void ConstructSessionFactories(IEnumerable<string> > connectionNames) { var maps = connectionMap.Map.Where(m > => connectionNames.Contains(m.Key)).Select(m => m.Value); > maps.ForEach(info => { if > (factoryMap.ContainsKey(info.ConnectionString)) return; > WaitForCompletionIfFactoryUnderConstruction(info.ConnectionString); > if (factoryMap.ContainsKey(info.ConnectionString)) return; > var task = new Task(() => CreateNewFactory(info)); > task.ContinueWith(FactoryConstructed, > TaskContinuationOptions.OnlyOnRanToCompletion); > task.ContinueWith(FactoryNotConstructed, > TaskContinuationOptions.NotOnRanToCompletion); > task.ContinueWith(FactoryConstructionCausedError, > TaskContinuationOptions.OnlyOnFaulted); > factoriesUnderConstruction[info.ConnectionString] = task; > task.Start(); }); } > > > protected virtual ISessionFactory CreateNewFactory(ConnectionElement > info) { if > (factoryMap.ContainsKey(info.ConnectionString)) return > factoryMap[info.ConnectionString]; logger.DebugFormat("Creating > new SessionFactory for connection '{0}'", info.Name); var cfg = > configurationProvider.Get(info); ExposeConfiguration(cfg); > configData.AddOrUpdate(info.Name, cfg, (key, oldValue) => cfg); > var factory = cfg.BuildSessionFactory(); > factoryMap[info.ConnectionString] = factory; return factory; > } > > > private void WaitForCompletionIfFactoryUnderConstruction(string > connection) { while > (factoriesUnderConstruction.ContainsKey(connection)) { > Task task; > factoriesUnderConstruction.TryGetValue(connection, out task); > if (task != null) task.Wait(); } } > > -- > You received this message because you are subscribed to the Google Groups > "nhusers" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] <javascript:>. > To post to this group, send email to [email protected] <javascript:> > . > Visit this group at http://groups.google.com/group/nhusers?hl=en-US. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/nhusers?hl=en-US. For more options, visit https://groups.google.com/groups/opt_out.
