2009-05-26 5 views
7

В моем веб-приложении я должен постоянно проверять действия пользователя. Поэтому всякий раз, когда пользователь предпринимает какое-либо действие, я обновляю объект, на котором выполняется действие, и сохраняю контрольный след этого действия.Использование транзакций с дозвуковым

Теперь, если я сначала модифицирую объект, а затем обновляю аудиторский след, но след аудита не удается, то что?

Очевидно, что мне нужно отменить изменения для измененного объекта. Я могу использовать Sql-Transactions в простом приложении, но я использую Subsonic для общения с db. Как я могу справиться с ситуацией?

ответ

10

Что-то вроде:

Using ts As New System.Transactions.TransactionScope() 
    Using sharedConnectionScope As New SubSonic.SharedDbConnectionScope() 

' Do your individual saves here 

' If all OK 
     ts.Complete() 

    End Using 
End Using 
+1

Я могу подтвердить, что TransactionScope корректно работает с SubSonic и выполняет откаты транзакции правильно. – kd7

+0

Спасибо @kevinw и @bnkdev. Я использую C#, поэтому я отправлю код на C#, чтобы он мог быть легко использован другими. Также не могли бы вы поместить отдельные сбережения или действия внутри try/catch, так что легче узнать, все ли ОК или нет? – TheVillageIdiot

14

The answer дается @Kevinw совершенно нормально. Я отправляю это как перевод своего ответа на код C#. Я не использую комментарии, поскольку он не будет форматировать код :) Также я использую try/catch, чтобы узнать, должна ли транзакция завершаться или откатываться.

using (System.Transactions.TransactionScope ts = new TransactionScope()) 
{ 
    using (SharedDbConnectionScope scs = new SharedDbConnectionScope()) 
    { 
     try 
     { 
      //do your stuff like saving multiple objects etc. here 

      //everything should be completed nicely before you reach this 
      //line if not throw exception and don't reach to line below 
      ts.Complete(); 
     } 
     catch (Exception ex) 
     { 
      //ts.Dispose(); //Don't need this as using will take care of it. 
      //Do stuff with exception or throw it to caller 
     } 
    } 
} 
+1

Вызов 'ts.Dispose()' внутри catch-clause не требуется, поскольку оператор using позаботится об этом. В общем случае это может вызвать проблемы, так как «SharedDbConnectionScope» или другой код транзакции, запущенный внутри области транзакции, может зависеть от того, будет ли он удален до того, как будет закрыта область действия транзакции. –

+0

@ OskarBerggren прокомментировал это. – TheVillageIdiot

1

Nope. Если я помещаю SharedDbConnectionScope вне изменений, это видимость в базе данных до ts.Complete(). Ввод его внутрь блокирует сервер до завершения операции.