5

我有几个方法调用需要执行,需要“事务性”,但我不确定除了 try/catch/finally 之外如何实现它。

背景

  • 应用程序是基于控制台的。
  • 应用程序将有多个线程
  • 查询数据库以获取连接信息,连接到 Web 服务以登录,生成会话 ID 并更新数据库。
  • 操作调用注销,需要清理数据库,清除会话ID,注销webservice

我想弄清楚的

我想确保在请求注销时,我想确保整个过程要么全部成功,要么根本不成功。例如,我不希望清理数据库、清理会话 ID 和注销操作失败(因此登录仍然有效)。

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

是否有一种巧妙的方法来实现这一点,或者我是否坚持使用一系列嵌套的 try/catch/finally 块来做到这一点?

4

3 回答 3

2

如果你想实现一些rollback方法,你必须为所有你需要回滚的东西存储撤消数据,以防万一失败。

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

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

于 2013-05-01T20:46:05.930 回答
0

“整洁”可能意味着这样的东西?(http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

但我更喜欢你提到的 KISS 结构......至少直到在使用复杂的语言/资源结构实现之前稳定工作......让它工作......然后让它更漂亮/快速/解耦/...

于 2013-05-01T21:30:14.420 回答
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);
    }
}

输出:

  • 原名:玛格
  • 捕获异常
  • 事情是:荷马
于 2014-03-13T16:13:26.073 回答