2013-05-01 70 views
3

我有几个需要执行的方法调用需要“事务性”,但我不确定如何从try/catch/finally中实现这一点。如何使一系列非数据库方法模拟事务。

背景

  • 申请基于控制台。
  • 应用程序将有多个线程
  • 查询数据库的连接信息,连接到web服务进行登录,生成会话ID和更新数据库。
  • 的操作调用注销,需要清理数据库,清除会话ID和登录web服务的出

我试图找出

我想确保在请求注销时,我要确保整个过程都是成功的,或者根本不是。例如,我不希望清理数据库,清除会话标识并注销操作失败(因此登录仍然有效)。

理想情况下,解决方案会在故障时“回滚”,从而确保保持之前的状态。

是否有一种很好的方法来完成这个任务,或者我坚持使用一系列嵌套的try/catch/finally块来做到这一点?

回答

1

如果您想实施一些rollback方法,则必须存储撤消数据,以查找在发生故障时需要回滚的所有事情。

  • 对于DB,您已经有一个回滚方法。
  • 对于您正在修改/删除操作中可能需要回滚的每个文件,您必须保留备份副本,以允许您恢复到之前的状态。
  • 任何可能必须回滚的内存中变量都应具有备份副本。

这将允许您在您的代码中的任何一点发生错误时回滚到以前的状态。

+1

这就是我所想的,基本上是try/catch/finally。数据库中的事务回滚仅适用于数据库本身,我仍然需要通过临时变量管理所有其他状态。 – 2013-05-01 20:47:25

+0

即使使用数据库事务,您也需要一个try/catch/finally块,以便在catch中回滚并最终关闭连接。如果您在所有失败的地方抛出异常,并将其捕获到最高级别,那么您可以减少此类块的数量,并在那里调用回滚方法。你最后的方法可以清除所有的临时变量/文件。 – Eran 2013-05-01 20:51:54

+0

是的。我想等待任何其他信息,我将不得不走这条路。啊,没什么冒险的,什么都没有增加。 – 2013-05-01 20:56:28

0

“整齐”可能意味着这样的事情?但是我更喜欢像你提到的KISS构造......至少直到在用复杂的语言/资源构造实现之前坚实工作......让它工作......然后让它更加漂亮/快速/ decoupled/...

0

对于这个问题的任何随便瞥见者,不要假设try/catch块是基本原子的。他们

证明代码:

public class TransactionTest { 

    private class Thing { 
     public int number = 1; 
     public String thingName = "Marge"; 

    } 

    public static void main(String args[]) { 
     new TransactionTest(); 
    } 

    public TransactionTest() { 
     transactionExperiment(); 
    } 

    private void transactionExperiment() { 

     Thing t = new Thing(); 
     try { 
      System.out.println("Original name: " + t.thingName); 
      t.thingName = "Homer"; 
      throw new IllegalArgumentException("Throw exception deliberately"); 
     } 
     catch(IllegalArgumentException e) { 
      System.out.println("Caught exception"); 
     } 

     System.out.println("Thing is: " + t.thingName); 
    } 
} 

输出:

  • 原名:玛吉
  • 捕捉到异常
  • 事情是:荷马