Nhibernate: обработка исключения ITransaction, чтобы новые транзакции могли продолжаться с той же ISession - PullRequest
11 голосов
/ 30 января 2009

У меня есть список из 10 объектов данных, которые я хочу вставить / обновить в базе данных с помощью NHibernate. Если одно выдает исключение (скажем, нарушение первичного ключа), я все равно хочу вставить / обновить другое 9. Я свернул каждую объектную операцию в свою собственную атомарную транзакцию и откатил транзакцию, если есть исключение. Проблема заключается в том, что если транзакция действительно вызывает исключение и откатывается, при следующей транзакции Nhibernate выдает сообщение об ошибке: пустой идентификатор в записи Nexus.Data.PortfolioCorporateEntity (не сбрасывать сеанс после возникновения исключения)

Моя основная программа проста. Он создает сеанс из фабрики сеансов, создает уровень доступа к данным, выполняет некоторую работу с объектами данных, а затем пытается сохранить эти объекты данных в базе данных.

    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());
            }

        }

Это процедура updateOrAdd в моем слое доступа к данным Nhibernate, вызываемая 10 раз для 10 объектов.

public void UpdateOrAddObject<T>(T workObject) 
{ 
    using (ITransaction tx = mSession.BeginTransaction) { 
        try { 
            mSession.SaveOrUpdate(workObject); 
            mSession.Flush(); 
            tx.Commit(); 
        } 
        catch (Exception ex) { 
            tx.Rollback(); 
            throw;
        } 
    } 
} 

Просто чтобы прояснить суть, сеанс создается вызывающей программой и передается объекту уровня доступа к данным, конструктор которого приведен ниже.

public NHibernateDataProvider(ISession session) 
{ 
    mSession = session; 
} 

Это работает нормально, за исключением исключения, оно говорит, что не стирайте сеанс после исключения. Я не уверен, почему - транзакция была отменена, и база данных должна быть готова принять другую транзакцию. Нет? Что я делаю не так?

Ответы [ 3 ]

9 голосов
/ 02 февраля 2009

Невозможно повторно использовать сеанс NHibernate после возникновения исключения. Цитирование документации :

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.

Так что ответ таков: вы не можете делать то, что пытаетесь сделать. Вам нужно создать новый сеанс и повторно попробовать обновления там.

6 голосов
/ 18 сентября 2010

Я очищаю сессию и она продолжается нормально


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);
    }
}

0 голосов
/ 02 февраля 2009

Спасибо за ответ. Просто хотел убедиться, что все сделано правильно. Вы говорите, что моя обработка ошибок должна быть просто изменена на:

        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;

            }
        }

Похоже, это работает просто отлично. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...