Сбросьте NHibernate при тихом разрешении отката транзакции

Я не видел указанного языка, но можно использовать это для PHP, он генерирует RegEx для каждой работы instered так, чтобы даже намеренные орфографические ошибки (т.е. @ss, i3itch) были также пойманы.

<?php

/**
 * @author unkwntech@unkwndesign.com
 **/

if($_GET['act'] == 'do')
 {
    $pattern['a'] = '/[a]/'; $replace['a'] = '[a A @]';
    $pattern['b'] = '/[b]/'; $replace['b'] = '[b B I3 l3 i3]';
    $pattern['c'] = '/[c]/'; $replace['c'] = '(?:[c C (]|[k K])';
    $pattern['d'] = '/[d]/'; $replace['d'] = '[d D]';
    $pattern['e'] = '/[e]/'; $replace['e'] = '[e E 3]';
    $pattern['f'] = '/[f]/'; $replace['f'] = '(?:[f F]|[ph pH Ph PH])';
    $pattern['g'] = '/[g]/'; $replace['g'] = '[g G 6]';
    $pattern['h'] = '/[h]/'; $replace['h'] = '[h H]';
    $pattern['i'] = '/[i]/'; $replace['i'] = '[i I l ! 1]';
    $pattern['j'] = '/[j]/'; $replace['j'] = '[j J]';
    $pattern['k'] = '/[k]/'; $replace['k'] = '(?:[c C (]|[k K])';
    $pattern['l'] = '/[l]/'; $replace['l'] = '[l L 1 ! i]';
    $pattern['m'] = '/[m]/'; $replace['m'] = '[m M]';
    $pattern['n'] = '/[n]/'; $replace['n'] = '[n N]';
    $pattern['o'] = '/[o]/'; $replace['o'] = '[o O 0]';
    $pattern['p'] = '/[p]/'; $replace['p'] = '[p P]';
    $pattern['q'] = '/[q]/'; $replace['q'] = '[q Q 9]';
    $pattern['r'] = '/[r]/'; $replace['r'] = '[r R]';
    $pattern['s'] = '/[s]/'; $replace['s'] = '[s S $ 5]';
    $pattern['t'] = '/[t]/'; $replace['t'] = '[t T 7]';
    $pattern['u'] = '/[u]/'; $replace['u'] = '[u U v V]';
    $pattern['v'] = '/[v]/'; $replace['v'] = '[v V u U]';
    $pattern['w'] = '/[w]/'; $replace['w'] = '[w W vv VV]';
    $pattern['x'] = '/[x]/'; $replace['x'] = '[x X]';
    $pattern['y'] = '/[y]/'; $replace['y'] = '[y Y]';
    $pattern['z'] = '/[z]/'; $replace['z'] = '[z Z 2]';
    $word = str_split(strtolower($_POST['word']));
    $i=0;
    while($i < count($word))
     {
        if(!is_numeric($word[$i]))
         {
            if($word[$i] != ' ' || count($word[$i]) < '1')
             {
                $word[$i] = preg_replace($pattern[$word[$i]], $replace[$word[$i]], $word[$i]);
             }
         }
        $i++;
     }
    //$word = "/" . implode('', $word) . "/";
    echo implode('', $word);
 }

if($_GET['act'] == 'list')
 {
    $link = mysql_connect('localhost', 'username', 'password', '1');
    mysql_select_db('peoples');
    $sql = "SELECT word FROM filters";
    $result = mysql_query($sql, $link);
    $i=0;
    while($i < mysql_num_rows($result))
     {
        echo mysql_result($result, $i, 'word') . "<br />";
        $i++;
     }
     echo '<hr>';
 }
?>
<html>
    <head>
        <title>RegEx Generator</title>
    </head>
    <body>
        <form action='badword.php?act=do' method='post'>
            Word: <input type='text' name='word' /><br />
            <input type='submit' value='Generate' />
        </form>
        <a href="badword.php?act=list">List Words</a>
    </body>
</html>
5
задан cbp 18 April 2011 в 08:29
поделиться

2 ответа

При использовании транзакций с NHibernate старайтесь избегать использования Session.Flush () и вместо этого используйте transaction.Commit (), которую он вызывает внутри session.flush ().

Если во время Commit () возникает ошибка, и транзакцию необходимо откатить, это можно решить следующим образом.

public static void CommitChanges()
{
    ITransaction transaction = Session.BeginTransaction();

    try
    {
        transaction.Commit();
    }
    catch (HibernateException ex)
    {
        transaction.Rollback();
        //close and dispose session here
        throw ex;
    }
    finally
    {
        transaction.Dispose();
    }
}

Теперь, если ручной вызов flush () или вызов commit () проходит успешно, нет способ отката транзакции с помощью механизмов NHibernate. При вызове команды transaction.Commit () AdoTransaction, созданный NHibernate, удаляется сразу после завершения Commit (), поэтому вы не можете получить к нему доступ для отката.

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

Теперь вместо вызова транзакции.Commit () в приведенном выше примере вы вызываете session.Flush () в моих тестах никакие данные не сохраняются в базе данных, поскольку транзакция никогда не фиксируется.

Я понятия не имею, как выглядит ваш код, но если вы вызываете в шаблоне, как показано выше в примере кода, это должно быть transaction.commit () вместо Session.Flush () дать вам возможность достичь желаемого.

2
ответ дан 14 December 2019 в 01:10
поделиться

Ради форматирования я позволю себе обновить ответ tolism7 здесь.

  1. используйте using и забудьте о transaction.Dispose() - transaction будет автоматически Dispose'd в конце блока using.
  2. throw - не бросайте ex, потому что это означает выброс трассировки стека (см. это сообщение, где говорится: "Когда .NET Framework выполняет это утверждение: throw ex; он отбрасывает всю информацию стека выше текущей функции.")

.

public void CommitChanges()
{
    using (var transaction = Session.BeginTransaction())  // <-- open scope
        try
        {
            // do something
            transaction.Commit();
        }
        catch (HibernateException)
        {
            transaction.Rollback();
            _session.Close();
            _session.Dispose();

            throw;  // <-- this way the stacktrace stays intact!
        }
}

Версию VB.NET этого куска кода можно найти здесь.

3
ответ дан 14 December 2019 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: