Делать Flush () внутри активной транзакции - PullRequest
0 голосов
/ 14 сентября 2010

У меня есть сценарий, с которым я обычно сталкиваюсь.Это просто сделать со стандартной транзакцией ADO, но не так много с NH (насколько я знаю).

У меня есть 2 таблицы для обновления.Первый содержит информацию о профиле (Profile), а другой (Work) содержит записи об изменениях, которые необходимо внести, и статус этих изменений.Для каждого обновления таблицы профиля будет обновляться статус в рабочей таблице.

  • Если обновление таблицы профилей завершится неудачно, мне нужно обновить статус в рабочей таблице.
  • Если обновление таблицы профиля прошло успешно, а обновление рабочей таблицы завершилось неудачно, мне нужно откатить транзакцию.

Проблема в том, что я не знаю,обновление таблицы профилей не удалось, пока я не совершу транзакцию.Я попытался выполнить очистку профиля, чтобы перехватить исключение, чтобы я мог записать состояние в рабочую таблицу, но затем произошел сбой моей фиксации с исключением, вызванным обновлением профиля.

Как я могу это обработать?В типичной транзакции ADO мой первый вызов сработает, но я могу перехватить и обновить все таблицы в транзакции.

Вот как выглядит мой код - довольно стандартный.Это не мой настоящий код, поэтому, пожалуйста, сосредоточьтесь на проблеме, а не на том, что я не удаляю транзакцию и не закрываю сеанс;):

try
{
    ITransaction trans = _session.BeginTransaction();

    var work = _repo.GetWork();
    var profile = _repo.GetProfile(work.ProfileId);

    try
    {
        profile.UpdateWithNewValues(work);
        _session.SaveOrUpdate(profile);
        _session.Flush();
        work.Status = "Success";

    }catch{
      work.Status = "Failure";
    }

    _session.SaveOrUpdate(work);
    trans.Commit();

}catch{

    trans.Rollback();

}

Я понимаю, что Flush () не будет работать, но я не знаю, как еще это сделать.

Ответы [ 2 ]

0 голосов
/ 15 сентября 2010

Требуются пояснения к вашим требованиям.

1) >> Если обновление таблицы профиля выполнено успешно, а обновление рабочей таблицы завершилось неудачно, мне нужно откатить транзакцию

Я бы подумал, что Работа похожа на обновление журнала аудита и не должна была произойти сбой, если обновление профиля работает. Если это так, то вам не следует откатывать транзакцию. Однако, сказав это, ваш код уже соответствует этому требованию.

2) >> Если обновление таблицы профиля не удается, мне нужно обновить состояние рабочей таблицы.

Если обновление завершится неудачно, вы откатите свою транзакцию. Вы не сможете обновить рабочую таблицу, если у вас нет двух отдельных транзакций (одна для профиля и работы (как текущая), а затем отдельная только для работы). Это имеет для вас смысл?

0 голосов
/ 15 сентября 2010

Я не вижу проблемы с trans.Commit до сброса. Вот пример (слегка измененный тоже похож на ваш):

Profile profile;
Work work;
ITransaction tx;

try
{
    session.SaveOrUpdate(profile);  

    work.Status = "Success";    
    session.SaveOrUpdate(work);

    tx.Commit();
}
catch (Exception)   // wroh oh...
{
    try
    {
        work.Status = "Failure";
        session.SaveOrUpdate(work);

        tx.Commit();
    }
    catch (Exception)
    {
        if (!tx.WasRolledBack)
        {
            tx.Rollback();
            session.Clear();
        }

        throw;
    }
}
finally
{
    if (session.IsOpen)
    {
        // Whatever happened, Flush/Persist at the end.
        session.Flush();
    }
}
...