我想用線程創建迷你會話和完全工廠。完整的會議工廠在第二個線程上。這個概念是用最小限度的做最初的登錄細節,並等待其他事情全面激情。我實現了線程,但是當代碼碰到buildsessionfactory(第二個)時出現了一些問題。當不在線程上時,代碼工作正常。我如何爲登錄細節等活動實施minisession。我認爲其中一個問題也是如何啓動線程(GetFullSessionFactoryFor)。迷你會話工廠和realsession工廠
public sealed class NHibernateSessionManager
{
static bool sessionFactoryReady = false;
#region Thread-safe, lazy Singleton
private string _sessionFactoryConfigPath = null;
public static NHibernateSessionManager Instance
{
get
{
return Nested.NHibernateSessionManager;
}
}
private NHibernateSessionManager() { }
private class Nested
{
static Nested() { }
internal static readonly NHibernateSessionManager NHibernateSessionManager =
new NHibernateSessionManager();
}
#endregion
private ISessionFactory GetSessionFactoryFor(string sessionFactoryConfigPath)
{
GetFullSessionFactoryFor(sessionFactoryConfigPath);
while (!sessionFactoryReady) Thread.Sleep(10000);
return (ISessionFactory)sessionFactories[sessionFactoryConfigPath];
}
private void GetFullSessionFactoryFor(string sessionFactoryConfigPath)
{
ThreadPool.QueueUserWorkItem(state =>
{
Check.Require(!string.IsNullOrEmpty(sessionFactoryConfigPath),
"sessionFactoryConfigPath may not be null nor empty");
ISessionFactory sessionFactory = (ISessionFactory)sessionFactories[sessionFactoryConfigPath];
if (sessionFactory == null)
{
Check.Require(File.Exists(sessionFactoryConfigPath),
"The config file at '" + sessionFactoryConfigPath + "' could not be found");
Configuration cfg = new Configuration();
cfg.SetInterceptor(new NHInterceptor());
cfg.Configure(sessionFactoryConfigPath);
FluentConfiguration fluentConfiguration = Fluently.Configure(cfg)
.Mappings(m =>
{
m.FluentMappings
.AddFromAssembly(Assembly.Load("someassembly"))
.Conventions.Add(DefaultLazy.Always(),
OptimisticLock.Is(x => x.All()),
DynamicUpdate.AlwaysTrue(),
DynamicInsert.AlwaysFalse(),
DefaultCascade.None()
)
.Conventions.AddFromAssemblyOf<"someDateconventionobject">()
;
});
;
sessionFactory = fluentConfiguration.BuildSessionFactory();
if (sessionFactory == null)
{
throw new InvalidOperationException("cfg.BuildSessionFactory() returned null.");
}
sessionFactories.Add(sessionFactoryConfigPath, sessionFactory);
cfg.SetInterceptor(new NHInterceptor());
cfg.Configure(sessionFactoryConfigPath);
fluentConfiguration = Fluently.Configure(cfg);
string userDataPath = cfg.GetProperty("connection.connection_string").ToUpper();
userDataPath = userDataPath.Replace("somevalue", "");
userDataPath = userDataPath.Replace(";somevalue", "");
string[] folderList = System.IO.Directory.GetDirectories(userDataPath);
bool firstFolder = true;
foreach (string folder in folderList)
{
if (System.IO.File.Exists(folder + "\\somedatabase"))
{
try
{
if (firstFolder)
{
fluentConfiguration = fluentConfiguration.ExposeConfiguration(c => c.SetProperty("sessionfactoryname", folder.ToLower()))
.ExposeConfiguration(c => c.SetProperty("connectionstring", ""))
.Mappings(m =>
{
m.FluentMappings
.AddFromAssembly(Assembly.Load("otherassembly"))
.Conventions.Add(DefaultLazy.Always(),
OptimisticLock.Is(x => x.All()),
DynamicUpdate.AlwaysTrue(),
DynamicInsert.AlwaysFalse(),
DefaultCascade.None()
)
.Conventions.AddFromAssemblyOf<"somedateconventionobject">()
;
}
)
;
}
else
{
fluentConfiguration = fluentConfiguration.ExposeConfiguration(c => c.SetProperty("sessionfactoryname", "name"))
.ExposeConfiguration(c => c.SetProperty("connectionstring", "value"));
}
sessionFactory = fluentConfiguration.BuildSessionFactory(); ------here is the problem
sessionFactories.Add(folder.ToLower(), sessionFactory);
}
catch (Exception e)
{
throw new EncoreException(e);
}
}
}
}
sessionFactoryReady = true;
});
}
public void RegisterInterceptorOn(string sessionFactoryConfigPath, IInterceptor interceptor, int sessionId)
{
ISession session = (ISession)ContextSessions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
if (session != null && session.IsOpen)
{
throw new CacheException("You cannot register an interceptor once a session has already been opened");
}
GetSessionFrom(sessionFactoryConfigPath, interceptor, sessionId);
}
public ISession GetSessionFrom(string sessionFactoryConfigPath, int sessionId)
{
return GetSessionFrom(sessionFactoryConfigPath, null, sessionId);
}
private ISession GetSessionFrom(string sessionFactoryConfigPath, IInterceptor interceptor, int sessionId)
{
ISession session = (ISession)ContextSessions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
if (session == null)
{
if (interceptor != null)
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession(interceptor);
}
else
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession();
}
session.FlushMode = FlushMode.Never;
ContextSessions[sessionFactoryConfigPath + "//" + sessionId.ToString()] = session;
}
Check.Ensure(session != null, "session was null");
return session;
}
public System.Data.IDbConnection GetDbConnection(string sessionFactoryConfigPath, int sessionId)
{
ISession session = GetSessionFrom(sessionFactoryConfigPath, sessionId);
return session.Connection;
}
public void CloseSessionOn(string sessionFactoryConfigPath, int sessionId)
{
ISession session = (ISession)ContextSessions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
if (session != null && session.IsOpen)
{
session.Close();
sessionList[sessionId] = false;
reuseSessionList.Push(sessionId);
}
ContextSessions.Remove(sessionFactoryConfigPath + "//" + sessionId.ToString());
}
public ITransaction BeginTransactionOn(string sessionFactoryConfigPath, int sessionId)
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
if (transaction == null)
{
transaction = GetSessionFrom(sessionFactoryConfigPath, sessionId).BeginTransaction();
ContextTransactions.Add(sessionFactoryConfigPath + "//" + sessionId.ToString(), transaction);
}
return transaction;
}
public void CommitTransactionOn(string sessionFactoryConfigPath, int sessionId)
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath, sessionId))
{
transaction.Commit();
ContextTransactions.Remove(sessionFactoryConfigPath + "//" + sessionId.ToString());
}
}
catch (HibernateException)
{
RollbackTransactionOn(sessionFactoryConfigPath, sessionId);
throw;
}
}
public bool HasOpenTransactionOn(string sessionFactoryConfigPath, int sessionId)
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
return transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack;
}
public void RollbackTransactionOn(string sessionFactoryConfigPath, int sessionId)
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath + "//" + sessionId.ToString()];
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath, sessionId))
{
transaction.Rollback();
}
ContextTransactions.Remove(sessionFactoryConfigPath + "//" + sessionId.ToString());
}
finally
{
}
}
public int GetSession()
{
int getSessionId = 0;
if (reuseSessionList.Count > 0)
{
getSessionId = reuseSessionList.Pop();
sessionList[getSessionId] = true;
}
else
{
getSessionId = nextSessionId;
sessionList.Add(true);
nextSessionId++;
}
return getSessionId;
}
private Hashtable ContextTransactions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[TRANSACTION_KEY] == null)
HttpContext.Current.Items[TRANSACTION_KEY] = new Hashtable();
return (Hashtable)HttpContext.Current.Items[TRANSACTION_KEY];
}
else
{
if (CallContext.GetData(TRANSACTION_KEY) == null)
CallContext.SetData(TRANSACTION_KEY, new Hashtable());
return (Hashtable)CallContext.GetData(TRANSACTION_KEY);
}
}
}
private Hashtable ContextSessions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[SESSION_KEY] == null)
HttpContext.Current.Items[SESSION_KEY] = new Hashtable();
return (Hashtable)HttpContext.Current.Items[SESSION_KEY];
}
else
{
if (CallContext.GetData(SESSION_KEY) == null)
CallContext.SetData(SESSION_KEY, new Hashtable());
return (Hashtable)CallContext.GetData(SESSION_KEY);
}
}
}
private bool IsInWebContext()
{
return HttpContext.Current != null;
}
private Hashtable sessionFactories = new Hashtable();
private const string TRANSACTION_KEY = "CONTEXT_TRANSACTIONS";
private const string SESSION_KEY = "CONTEXT_SESSIONS";
private List<bool> sessionList = new List<bool>();
private Stack<int> reuseSessionList = new Stack<int>();
private int nextSessionId = 0;
}
不要。只是...不。 – 2012-02-03 19:16:58