Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nhibernate:处理ITransaction异常,以便新事务可以继续使用相同的ISession_Nhibernate - Fatal编程技术网

Nhibernate:处理ITransaction异常,以便新事务可以继续使用相同的ISession

Nhibernate:处理ITransaction异常,以便新事务可以继续使用相同的ISession,nhibernate,Nhibernate,我有一个10个数据对象的列表,我想使用NHibernate插入/更新到数据库中。如果其中一个抛出异常(比如主键冲突),我仍然希望插入/更新另一个9。我将每个对象操作回滚到它自己的原子事务中,并在出现异常时回滚事务。问题是,如果某个事务确实导致异常并被回滚,则在下一个事务上,Nhibernate会投诉错误:Nexus.Data.PortfolioCorporateEntity条目中的id为null(发生异常后不要刷新会话) 我的主程序很简单。它从sessionfactory创建会话,创建数据访问层

我有一个10个数据对象的列表,我想使用NHibernate插入/更新到数据库中。如果其中一个抛出异常(比如主键冲突),我仍然希望插入/更新另一个9。我将每个对象操作回滚到它自己的原子事务中,并在出现异常时回滚事务。问题是,如果某个事务确实导致异常并被回滚,则在下一个事务上,Nhibernate会投诉错误:Nexus.Data.PortfolioCorporateEntity条目中的id为null(发生异常后不要刷新会话)

我的主程序很简单。它从sessionfactory创建会话,创建数据访问层,对数据对象执行一些操作,然后尝试将这些数据对象持久化到数据库

    sessionsManager = new NHibernateSessionManager();
        session = sessionsManager.GetSession();
        DALC = new NHibernateDataProvider(session);

        …

        foreach (var pce in pces)
        {
            try
            {
                DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString());
            }

        }

这可以正常工作,除非在异常之后,它说不要在异常之后刷新会话。我不知道为什么–事务被很好地回滚,数据库应该准备好接受另一个事务否?我做错了什么?

引发异常后,不可能重新使用NHibernate会话:


所以答案是你不能做你想做的事。您需要创建一个新会话,然后在那里重新尝试更新。

感谢您的回复。我只是想确定事情做对了。您的意思是,我的错误处理应该简单地更改为:

        foreach (var pce in pces)
        {
            try
            {
                DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString());

                session.Close();
                session = sessionsManager.GetSession();
                DALC.Session = session;

            }
        }
foreach(pce中的var pce)
{
尝试
{
DALC.更新放射性项目(pce);
}
捕获(例外情况除外)
{
Console.WriteLine(“无法添加公司实体ID”+pce.CorporateEntity.CorporateEntityID.ToString());
session.Close();
session=sessionmanager.GetSession();
DALC.会话=会话;
}
}

看起来这个很好用。谢谢。

我已清除会话,会话将正常继续


ISession session = NHibernateHelper.Session;
using (ITransaction transaction = session.BeginTransaction())
{
    try
    {
        session.Update(user, user.UserID);
        transaction.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        session.Clear();
        throw new DALException("Cannot update user", ex);
    }
}

从你发布的内容来看,这似乎会奏效。这实际上取决于DALC类的实现。此解决方案(session.Close/reopen)与上述仅使用session.Clear()的解决方案之间是否存在差异?有效!这是省道吗?只需使用“session.Clear()”即可重新启动会话?@sh_kamalh谢谢你,伙计!我也面临着同样的问题,并在寻找这样一个简单的解决方案。
If the ISession throws an exception you should immediately rollback the
transaction, call ISession.Close() and discard the ISession instance.
Certain methods of ISession will not leave the session in a consistent state.
        foreach (var pce in pces)
        {
            try
            {
                DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString());

                session.Close();
                session = sessionsManager.GetSession();
                DALC.Session = session;

            }
        }

ISession session = NHibernateHelper.Session;
using (ITransaction transaction = session.BeginTransaction())
{
    try
    {
        session.Update(user, user.UserID);
        transaction.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        session.Clear();
        throw new DALException("Cannot update user", ex);
    }
}