2013-09-05 4 views
2

У меня есть код, который считывает из таблицы список писем, которые нужно отправить и отправлять.Автоматические вызовы и откаты базы данных

Операции в порядке являются:

  1. установить флаг, как послал в таблице
  2. сделать автоматический вызов
  3. совершить

Причина, по которой обновление до того автоматический вызов заключается в том, что если что-то не удается, я могу откатиться и не совершать автоматический вызов. Но если бы все было наоборот, я попал бы в возможный сценарий, когда я делаю звонок, не имея возможности обновить запись (если что-то пойдет не так с db).

public class MyDao { 

    public void doSomethingOnDb() { 
     try { 
      // operation 1 : execute an update (setting the letter as sent) 
      // operation 2 : make automatic call  
      // operation 3 : commit 
     } 
     catch(Exception e) { 
      // Rollback 
     } 
    } 
} 

Что мне не нравится в том, что я размещая функциональность автоматических вызовов внутри дао, и это не то, что дао, как ожидается, сделать. Но если я отделяю логику, я не могу быть уверен, что флаг в таблице правдив. Мы можем сделать вызов и быть не в состоянии обновить флаг в БД:

public class MyDao { 

    public void doSomethingOnDb() { 
     try { 
      // operation 1 : execute an update (setting the letter as sent) 
      // operation 2 : commit 
     } 
     catch(Exception e) { 
      // Rollback 
     } 

    } 
} 

public void someOtherMethodSomewhere() { 
    try { 
     new MyDao().doSomethingOnDb(); 
     // operation 3 : make the automatic call 
    } 
    catch(Exception e) { 
    } 
} 

Итак, как бы вы это сделать? Есть ли другое решение?

ответ

0

Это классическая транзакция с несколькими ресурсами (распределенная транзакция). Я бы рекомендовал вам прочитать о XA-транзакциях и, например, Two Phase Commit protocol.

Возможно, вы пытаетесь решить другую проблему? Если я это правильно понял, возможно, вам просто нужно изменить свой код? Например. вы могли бы вернуть успех с дао:

if(doSomethingOnDb()) 
{ 
    //make the automatic call 
} 

т.е. вызов дао возвращает истину, если изменения сделаны успешно и совершенные.

Вы также можете просто выбросить исключение из doSomethingOnDb, если это не удается, в этом случае

try { 
    new MyDao().doSomethingOnDb(); 
    // operation 3 : make the automatic call 
} 
catch(Exception e) { 
} 

скачет operation 3 и попадает в блок улова.

Или просто перейти к дао запускаемую функцию:

public void doSomethingOnDb(Runnable precommit) { 
    try { 
     // operation 1 : execute an update (setting the letter as sent) 
     precommit.run();  
     // operation 3 : commit 
    } 
    catch(Exception e) { 
     // Rollback 
    } 
} 

... 
myDao.doSomethingOnDb(new Runnable() 
{ 
    void run() 
    { 
     // operation 3 : make the automatic call 
    } 
}); 
0

Не можете вы просто отделить операции DAO в submethods? Что-то вроде:

public class MyDao { 
    public void executeAnUpdate() {...} 
    public void commit() {...} 
} 

public class MyBusiness { 
    public void run() { 
     myDao.executeAnUpdate(); 
     // make the automatic call 
     myDao.commit(); 
    } 
} 
+0

Хорошо, возможно, создав даже метод откат тогда. Но он менее ослаблен таким образом – user1883212

Смежные вопросы