我想使用线程创建迷你会话和fullsession工厂。完整的会话工厂在第二个线程。这个概念是用minisession做初始登录细节,等待其他事情的完整。我实现了线程,但是当代码遇到buildsessionfactory时(第二个)存在一些问题。当不在线程上代码工作正常。我如何实现minisession仅用于登录详细信息等活动。我认为其中一个问题也是如何启动线程(GetFullSessionFactoryFor)。
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;
}
答案 0 :(得分:0)
GetSessionFrom().Connection
甚至更好GetSessionFrom().CreateSqlQuery()
所以没有获得任何价值我不明白你的子目录的逻辑,所以我把它们排除在外。如果你解释这个想法,我可以看看我是否可以拿出更好的代码来处理它们
您的代码的修订版
public sealed class NHibernateSessionManager
{
// Constants
private const string FACTORY_KEY = "CONTEXT_FACTORIES";
private const string SESSION_KEY = "CONTEXT_SESSIONS";
private const string TRANSACTION_KEY = "CONTEXT_TRANSACTIONS";
private IDictionary<string, ISessionFactory> SessionFactories = new Dictionary<string, ISessionFactory>();
// not really nessesary because creating NHibernateSessionManager is very cheap
#region Thread-safe, lazy Singleton
private NHibernateSessionManager() { }
public static NHibernateSessionManager Instance
{
get { return Nested.NHibernateSessionManager; }
}
private class Nested
{
static Nested() { }
internal static readonly NHibernateSessionManager NHibernateSessionManager =
new NHibernateSessionManager();
}
#endregion
private ISessionFactory GetSessionFactoryFor(string sessionFactoryConfigPath)
{
Check.Require(!string.IsNullOrEmpty(sessionFactoryConfigPath), "sessionFactoryConfigPath may not be null nor empty");
ISessionFactory sessionFactory = SessionFactories[sessionFactoryConfigPath];
if (sessionFactory == null)
{
// logic to configure and build the factory
Check.Require(File.Exists(sessionFactoryConfigPath),
"The config file at '" + sessionFactoryConfigPath + "' could not be found");
Configuration cfg = new Configuration()
.Configure(sessionFactoryConfigPath)
.SetInterceptor(new NHInterceptor());
string assemblypath = Path.Combine(Path.GetDirectoryName(sessionFactoryConfigPath), "whatever");
Assembly assembly = Assembly.Load(assemblypath);
sessionFactory = Fluently.Configure(cfg)
.Mappings(m => m.FluentMappings
.AddFromAssembly(assembly)
.Conventions.Add(
DefaultLazy.Always(),
OptimisticLock.Is(x => x.All()),
DynamicUpdate.AlwaysTrue(),
DynamicInsert.AlwaysFalse(),
DefaultCascade.None())
.Conventions.AddAssembly(assembly))
.BuildSessionFactory();
if (sessionFactory == null)
{
throw new InvalidOperationException("cfg.BuildSessionFactory() returned null.");
}
SessionFactories.Add(sessionFactoryConfigPath, sessionFactory);
// !!!DirectoryLogic ommitted because doesn't understand at all!!!
}
return sessionFactory;
}
private IDictionary<Guid, ISession> Sessions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[SESSION_KEY] == null)
HttpContext.Current.Items[SESSION_KEY] = new Dictionary<Guid, ISession>();
return (IDictionary<Guid, ISession>)HttpContext.Current.Items[SESSION_KEY];
}
else
{
if (CallContext.GetData(SESSION_KEY) == null)
CallContext.SetData(SESSION_KEY, new Dictionary<string, ISession>());
return (IDictionary<Guid, ISession>)CallContext.GetData(SESSION_KEY);
}
}
}
private IDictionary<Guid, ITransaction> Transactions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[TRANSACTION_KEY] == null)
HttpContext.Current.Items[TRANSACTION_KEY] = new Dictionary<Guid, ITransaction>();
return (IDictionary<Guid, ITransaction>)HttpContext.Current.Items[TRANSACTION_KEY];
}
else
{
if (CallContext.GetData(TRANSACTION_KEY) == null)
CallContext.SetData(TRANSACTION_KEY, new Dictionary<string, ITransaction>());
return (IDictionary<Guid, ITransaction>)CallContext.GetData(TRANSACTION_KEY);
}
}
}
private bool IsInWebContext()
{
return HttpContext.Current != null;
}
#region public
public Guid CreateSessionFor(string sessionFactoryConfigPath)
{
return CreateSessionFor(sessionFactoryConfigPath, null);
}
public Guid CreateSessionFor(string sessionFactoryConfigPath, IInterceptor interceptor)
{
var factory = SessionFactories[sessionFactoryConfigPath];
if (factory == null)
{
factory = GetSessionFactoryFor(sessionFactoryConfigPath);
SessionFactories[sessionFactoryConfigPath] = factory;
}
ISession session;
if (interceptor != null)
session = factory.OpenSession(interceptor);
else
session = factory.OpenSession();
Guid sessionId = session.GetSessionImplementation().SessionId;
Sessions.Add(sessionId, session);
return sessionId;
}
public ISession GetSession(Guid sessionId)
{
var session = Sessions[sessionId];
Check.Ensure(session != null, "there is no session with id '" + sessionId + "'");
return session;
}
public void CloseSession(Guid sessionId)
{
ISession session = Sessions[sessionId];
if (session != null && session.IsOpen)
{
session.Close();
}
Sessions.Remove(sessionId);
}
public ITransaction BeginTransactionOn(Guid sessionId)
{
ITransaction transaction = Transactions[sessionId];
if (transaction == null)
{
transaction = GetSession(sessionId).BeginTransaction();
Transactions.Add(sessionId, transaction);
}
return transaction;
}
public void CommitTransactionOn(Guid sessionId)
{
ITransaction transaction = Transactions[sessionId];
try
{
if (transaction != null && transaction.IsActive)
{
transaction.Commit();
}
}
catch (HibernateException)
{
transaction.Rollback();
throw;
}
finally
{
Transactions.Remove(sessionId);
}
}
public void RollbackTransactionOn(Guid sessionId)
{
ITransaction transaction = Transactions[sessionId];
try
{
if (transaction != null && transaction.IsActive)
{
transaction.Rollback();
}
}
finally
{
Transactions.Remove(sessionId);
}
}
#endregion
}