From f85c3429944ef506b73b9812f86200f9cc2c688e Mon Sep 17 00:00:00 2001 From: markpollack Date: Wed, 9 Jun 2010 15:15:57 +0000 Subject: [PATCH] SPRNET-1336 - Update documentation for MultiDelegatingDbProvider to show preferred way to set DbProvider name and notes for (not) using with NHibernate. --- doc/reference/src/dbprovider.xml | 65 +++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/doc/reference/src/dbprovider.xml b/doc/reference/src/dbprovider.xml index c47b7625..8976e9cc 100644 --- a/doc/reference/src/dbprovider.xml +++ b/doc/reference/src/dbprovider.xml @@ -208,11 +208,9 @@ - - MySql-6.2.2 (aliased to - MySql.Data.MySqlClient) - MySQL, MySQL provider - 6.2.2.0 - + MySql-6.2.2 (aliased to + MySql.Data.MySqlClient) - MySQL, MySQL provider + 6.2.2.0 @@ -574,21 +572,29 @@ the multiple databases and can be used in DAO layer such that the DAO layer is unaware of the switching between databases. MultiDelegatingDbProvider does its job by looking - into thread local storage under the key dbProviderName. This storage - location stores the name of the dbProvider that is to be used for - processing the request. MultiDelegatingDbProvider is - configured using the dictionary property - TargetDbProviders. The key of this dictionary - contains the name of a dbProvider and its value is a dbProvider object. - (You can also provide this dictionary as a constructor argument.) + into thread local storage. This storage location stores the name of the + dbProvider that is to be used for processing the request. + + + MultiDelegatingDbProvider is configured using + the dictionary property TargetDbProviders. The key of + this dictionary contains the name of a dbProvider and its value is a + dbProvider object. You can also provide this dictionary as a constructor + argument. The property DefaultDbProvider can be set + with the name of the DbProvider to use if no provider name is found in + thread local storage During request processing, once you have determined which target dbProvider should be use, in this example database1ProviderName, you should execute the following code is you are using Spring 1.2 M1 or later - // Spring 1.2 M1 or later -LogicalThreadContext.SetData(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME, "database1ProviderName") + // Spring 1.3.0 or later +MultiDelegatingDbProvider.CurrentDbProviderName = "database1ProviderName" + +// Spring 1.2 M1 or later +LogicalThreadContext.SetData(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME, "database1ProviderName") + and the following ocde if you are using earlier versions @@ -597,6 +603,16 @@ and then call the data access layer. + + If you do not change the name of the IDbProvider stored in + thread local storage during request processing, say in the web tier + where a user is identified, then you will always refer to the default + provider if the property DefaultDbProvider has + been set. If the DefaultDbProvider property has + not been set than an InvalidDataAccessApiUsageException will be + thrown. + + Here is a sample configuration to build up an object definition for MultiDelegatingDbProvider. @@ -615,7 +631,28 @@ <object id="DbProvider" type="Spring.Data.MultiDelegatingDbProvider, Spring.Data"> <property name="TargetDbProviders" ref="dbProviderDictionary"/> + <property name="DefaultDbProvider" value="CreditDbProvider"/> </object> + + As seen above, MultidelegatingDbProvider works via a thread local + storage mechansims. If you prefer to place the logic to switch databases + in a single location, within a single class, then create a subclass + MultiDelegatingDbProvider and override the method GetTargetProvider. You + can then select which provider to return based on your own + implementation that does not involve thread local storage. + + + This class is not recommended for usage with NHibernate. + NHibernate usage typically involves caches that are scoped at the + level of the SessionFactory. If you switch the database that hibernate + is pointing to and do not also managed switching the cache, then the + cache will end up with results from two different databases - which of + course you don't want to have. The helper class contained in this + post + may help you if you when using NHibernate with multiple + databases. +