sách gpt4 ai đã đi

NHibernate session 管理

In lại 作者:行者123 更新时间:2023-12-04 18:19:18 43 4
mua khóa gpt4 Nike

我在 win 服务中使用 NHiberante。有时我得到

System.ObjectDisposedException: Session is closed!
Object name: 'ISession'.
at NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed()
at NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus()
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at Attraction.DAL.Repositories.Repository`1.Save(T entity)
at Attraction.VideoDispatcher.Program.ThreadPoolCallback(Object threadContext)

我不知道出了什么问题。
我的 session 管理子系统:

存储库:
 public class Repository : IRepository, IDisposable
{
protected readonly bool CommitAtDispose;
public Repository(bool commitAtDispose)
{
CommitAtDispose = commitAtDispose;
StartSession();
}
private void StartSession()
{
if (NHibernateSession == null)
NHibernateHelper.StartSession();
}
public void Dispose()
{
if (CommitAtDispose)
Flush();
}
public void Flush()
{
NHibernateHelper.EndSession();
}
protected override sealed ISession NHibernateSession
{
lấy
{
return SessionManager.CurrentSession;
}
}
public virtual T GetById(int id)
public virtual List GetAll()
public virtual List GetByPage(int pageIndex, int pageSize)
public virtual int GetCount()
public virtual List GetByCriteria(params ICriterion[] criterion)
public virtual T Save(T entity)
public virtual T Update(T entity)
public virtual void Delete(T entity)
}
}

SessionManager - 提供对 sessionfactory 的访问的单音
public class SessionManager : ISessionFactoryProvider
{
private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly ISessionFactory sessionFactory;
public static ISessionFactory SessionFactory
{
get { return Instance.sessionFactory; }
}
public ISessionFactory GetSessionFactory()
{
return sessionFactory;
}
public static ISession OpenSession()
{
return Instance.GetSessionFactory().OpenSession();
}
public static ISession CurrentSession
{
lấy
{
if (!CurrentSessionContext.HasBind(Instance.GetSessionFactory()))
trả về giá trị null;
return Instance.GetSessionFactory().GetCurrentSession();
}
}


public static SessionManager Instance
{
lấy
{
return NestedSessionManager.sessionManager;
}
}
private SessionManager()
{
Log.Info("Start creating factory");
Configuration configuration = new Configuration().Configure();
sessionFactory = configuration.BuildSessionFactory();
Log.Info("End creating factory");

}

class NestedSessionManager
{
internal static readonly SessionManager sessionManager =
new SessionManager();
}
}

NhibernateHelper,它为开始和结束 session 做一些工作:
public static class NHibernateHelper
{
public static void StartSession()
{
var session = SessionManager.SessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);

}
public static void EndSession()
{
var session = SessionManager.CurrentSession;
CurrentSessionContext.Unbind(SessionManager.SessionFactory);
if (session != null)
{
thử
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Commit();
}
catch (Exception ex)
{
session.Transaction.Rollback();
throw new ApplicationException("Error committing database transaction. "+ex.Message, ex);
}
Cuối cùng
{
session.Close();
session.Dispose();

}
}


}
}

可能是我的设计不太好,但我无法想象我怎么能捕获这个错误。

làm mới

对不起我的配置。我还没有迁移到流利的,所以:


NHibernate.Connection.DriverConnectionProvider
NHibernate.Dialect.MySQLDialect
NHibernate.Driver.MySqlDataDriver
***
false
**_***
thread_static




UPD2

保存方法:
        public virtual T Save(T entity)
{
NHibernateSession.Save(entity);
return entity;
}

线程池回调:
        public static void DetectStart(Object threadContext)
{
thử
{
var task = (TasksPerAttraction)threadContext;
var startInfo = new ProcessStartInfo(..., ...)
{
UseShellExecute = false,
RedirectStandardOutput = true
};
Process p = Process.Start(startInfo);
var outputXml = p.StandardOutput.ReadToEnd();
p.WaitForExit();
var doc = XDocument.Parse(outputXml);
foreach (var xElement in doc.Root.Descendants("start"))
{
var startDetection = new StartDetection
{
DtStart = DateTime.Parse(xElement.Attribute("startTime").Value),
Attraction = task.Attraction,
};
lock (spinLock)
{
using (var repo = new Repository(true))
repo.Save(startDetection);
}
}
var tskRepo = new Repository(true);
foreach(var tsk in task.Tasks)
{
tsk.IsProcessedStart = true;
tskRepo.Update(tsk);
}
tskRepo.Flush();
}
catch (Exception ex)
{
//....
}
}

1 Câu trả lời

有一些潜在的问题,但我怀疑最大的问题是您将任务保存在一个 session 中(因此该任务的吸引力与 session 1 相关联),然后将任务保存在另一个 session 中 - 所以您以 session 1 中的 Attraction 结束,该 session 现已关闭, session 2 正在导航关系以查看是否需要保存 Attraction 并因此出现错误。这是一个假设,因为我没有您的模型或映射。

我认为最简单的解决方法是在您的回调中打开 session ,即:

public static void DetectStart(Object threadContext)
{
thử
{
... run your process ...
p.WaitForExit();
// **** OPEN SESSION HERE ****
NHibernateHelper.StartSession();

var doc = XDocument.Parse(outputXml);
foreach (var xElement in doc.Root.Descendants("start"))
{
var startDetection = new StartDetection
{
DtStart = DateTime.Parse(xElement.Attribute("startTime").Value),
Attraction = task.Attraction,
};
lock (spinLock)
{
// *** DON'T CLOSE THE SESSION ON DISPOSE
using (var repo = new Repository(false))
repo.Save(startDetection);
}
}
// *** DON'T CLOSE THE SESSION ON DISPOSE HERE EITHER!
using(var tskRepo = new Repository(false))
{
foreach(var tsk in task.Tasks)
{
tsk.IsProcessedStart = true;
tskRepo.Update(tsk);
}
tskRepo.Flush();
}
}
catch (Exception ex)
{
//....
}
finally {
// *** MAKE SURE YOU CLOSE THE SESSION
NHibernateHelper.EndSession();
}
}

关于NHibernate session 管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11011877/

43 4 0
Bài viết được đề xuất: grep - 使用 grep 过滤 Doxygen 输出
Bài viết được đề xuất: jsf-2 - a4j :commandButton passing values in callback
Bài viết được đề xuất: c# - Visual Studio SOAP 服务引用客户端 : see XML message
Bài viết được đề xuất: jena - Jena读取Protege本体文件报错怎么办?
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com