Perl DBI begin_work и вложенные транзакции, взаимодействующие с SQL Server 2008 - PullRequest
3 голосов
/ 06 июня 2011

У меня есть сценарий, как показано ниже.Где основной метод должен вызывать несколько методов, 1 метод для 1 таблицы, и каждый метод выполняет набор операторов, который должен быть атомарным.Таким образом, они заключены в блок begin_work, commit, rollback.

Также call_method_for_table1, call_method_for_table2, call_method_for_table3 должны все успешно завершиться или потерпеть неудачу вместе, что означает, что они должны быть атомарными.Поэтому в основной метод добавляются также begin_work, commit, rollback block.Но я вижу, что Perl не позволяет мне.Я получаю исключение - "Ошибка DBD :: ODBC :: db begin_work: уже в транзакции" .Теперь у меня нет никакого способа изменить методы call_method_for_table *, поскольку он находится в библиотеке, и изменить его невозможно по многим причинам.

Могу ли я использовать контрольные точки для решения этой проблемы

  1. Помогут ли точки сохранения (http://msdn.microsoft.com/en-us/library/ms378414%28v=SQL.105%29.aspx)
  2. Откат будет работать до момента сохранения, даже если между ними есть какие-то коммиты (что обычно происходит в моем примере)
  3. Нормально ли это, даже если параллельные запуски одного и того же процесса выполняются?
  4. Приведет ли это к несогласованности данных?
sub main {
        $dbh->begin_work;
           eval {
              call_method_for_table1();
              call_method_for_table2();
              call_method_for_table3();
              $dbh->commit;
              1; 
        };

        if ($@) {
              $dbh->rollback; }
       }

    sub call_method_for_table1 {
    $dbh->begin_work;
           eval {
           $dbh->do($INSERTSTATEMENT_TABLE1);
           $dbh->do($UPDATESTATEMENT_TABLE1);
           $dbh->do($DELETESTATEMENT_TABLE1);
           $dbh->commit; 
           };

           if ($@) {
             $dbh->rollback;
           }
    }

1 Ответ

1 голос
/ 06 июня 2011

Я думаю, что это невозможно без изменения call_method_for_tableX.

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

...