我有一個使用絕對最新版本(3.3)的Web應用程序,並且在HttpModule中使用按會話請求會話管理,所以多個會話衝突沒有問題。不幸的是,我發現在我執行一個Transaction.Commit後,會話會立即自動關閉,我只在實際執行Create,Update或Delete時纔會執行此操作。我在我的NHibernate日誌中發現這個。NHibernate Transaction.Commit自動關閉會話
我知道一個事實,我沒有這樣做,因爲唯一的ISession.Close函數調用正在我的HttpModule中完成。
是的,當然,我可以在我的SessionManager中放入代碼來檢查IsClosed參數,然後使用OpenSession函數而不是GetCurrentSession,但是這應該發生嗎?有什麼方法可以通過我的配置或我可以在Session或Transaction對象上設置的屬性來防止這種情況,或者這只是我無法在任何地方找到任何文檔的新功能之一?
請幫忙。
布賴恩
我被要求提供一些代碼,所以這裏是爲HTTP模塊的代碼:
public class NhibernateModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
}
public void context_BeginRequest(Object sender, EventArgs e)
{
WebSessionContext.Bind(NhibernateSessionManager.GetContextSession());
}
public void context_EndRequest(Object sender, EventArgs e)
{
ISession session = WebSessionContext.Unbind(NhibernateSessionManager.SessionFactory);
if (session != null)
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
}
else
session.Flush();
session.Close();
}
}
}
}
接下來,你會發現,我現在用的是原來的代碼在我的SessionManager中:
public sealed class NhibernateSessionManager
{
private readonly ISessionFactory sessionFactory;
public static ISessionFactory SessionFactory
{
get { return Instance.sessionFactory; }
}
private ISessionFactory GetSessionFactory()
{
return sessionFactory;
}
public static NhibernateSessionManager Instance
{
get { return NestedSessionManager.sessionManager; }
}
public static ISession GetContextSession()
{
ISession session;
if (CurrentSessionContext.HasBind(SessionFactory))
{
session = SessionFactory.GetCurrentSession();
}
else
{
session = SessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
}
return session;
}
private NhibernateSessionManager()
{
if (sessionFactory == null)
{
Configuration configuration;
configuration = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config"));
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config")));
//Configuration configuration = new Configuration().Configure();
if (configuration == null)
{
throw new InvalidOperationException("NHibernate configuration is null.");
}
else
{
sessionFactory = configuration.BuildSessionFactory();
if (sessionFactory == null)
throw new InvalidOperationException("Call to BuildSessionFactory() returned null.");
}
}
}
class NestedSessionManager
{
internal static readonly NhibernateSessionManager sessionManager = new NhibernateSessionManager();
}
}
最後,這裏是一個函數,當前causi在Transaction.Commit()之後立即關閉會話。每個內部函數檢索當前會話,然後處理一個保存呼叫。
public static Int32 AddVideo(VideoFile Video, Int32 UserID, Int16 InstID)
{
log.Debug("Begin AddVideo");
Int32 FileID = 0;
using (ISession Session = NhibernateSessionManager.GetContextSession())
{
using (ITransaction Transaction = Session.BeginTransaction())
{
Video.Created = DateTime.Now;
Video.Modified = DateTime.Now;
FileID = (Int32)Session.Save(Video);
Video.FileID = FileID;
// Need to process through all the categories and insert records into the ivxFileCategories table
// to associate the newly created file with the chosen categories
if (Video.CategoryAssociations != null)
{
log.Info("Number of categories to be associated with the video: " + Video.CategoryAssociations.Count);
for (int i = 0; i < Video.CategoryAssociations.Count; i++)
{
CategoryFileAssociation Assoc = (CategoryFileAssociation)Video.CategoryAssociations[i];
Assoc.FileID = FileID;
AssociationManager.AddCategoryFileTransaction(Assoc);
}
}
// Need to add the default file access for the UserDetail that is creating the new video which will always
// be Admin because the UserDetail creating a file should always have admin access over the file, no matter
// what their default role is.
AssociationManager.AddFileAccessTransaction(FileID, UserID, UserClassConstants.IVXUSERCLASS_ADMIN);
// Need to add the institutional association based on whether the new video was created by a librarian
// or one of the iVidix admins
AssociationManager.AddInstitutionFileTransaction(InstID, FileID);
Transaction.Commit();
}
}
log.Debug("End AddVideo");
return FileID;
}
您是否使用嵌套事務?你在什麼時候打電話?提交?我們可以看到一些保存代碼和HttpModule的代碼。 – Rippo