Java 如何使一系列非数据库方法模拟事务。

Java 如何使一系列非数据库方法模拟事务。,java,transactions,Java,Transactions,我需要执行几个方法调用,这些调用需要是“事务性的”,但除了try/catch/finally之外,我不确定如何实现 背景 应用程序是基于控制台的 应用程序将有多个线程 查询数据库以获取连接信息,连接到Web服务进行登录,生成会话ID并更新数据库 操作调用注销,注销需要清理数据库、清除会话ID并注销Web服务 我想弄明白什么 我想确保当要求注销时,我想确保整个过程要么全部成功,要么根本没有成功。例如,我不希望数据库被清理,会话ID被清理,注销操作失败(因此登录仍然有效) 理想情况下,解决方案将

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

背景

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

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

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


是否有一种巧妙的方法来实现这一点,或者我是否需要一系列嵌套的try/catch/finally块来实现这一点

如果要实现某个
回滚
方法,则必须为发生故障时需要回滚的所有内容存储撤消数据

  • 对于DB,您已经有了回滚方法
  • 对于您在操作中修改/删除的每个可能需要回滚的文件,您必须保留一个备份副本,以便恢复到以前的状态
  • 任何可能必须回滚的内存中变量都应该有备份副本
这将允许您在发生错误时,在代码中的任何时候回滚到以前的状态。

“整洁”可能意味着这样的意思? ()


但是我更喜欢你提到的KISS结构…至少在使用复杂的语言/资源结构实现之前,要先稳定地工作…让它工作起来…然后让它变得更漂亮/快速/解耦/…

对于这个问题的任何漫不经心的人来说,不要假设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);
    }
}
输出:

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);
    }
}
  • 原名:玛姬
  • 抓住例外
  • 事情是:荷马

这就是我所想的,本质上是尝试/抓住/最终。数据库中的事务回滚只适用于数据库本身,我仍然必须通过临时变量管理所有其他状态。即使使用DB事务,也需要try/catch/finally块,以便在catch中回滚并关闭finally连接。如果在所有失败的地方抛出异常,并在顶层捕获它们,在顶层调用回滚方法,则可以减少此类块的数量。您的finally方法可以清除所有临时变量/files.True。我想在没有其他消息之前,我得走那条路。嗯,没有冒险,没有收获。好的答案,但我也将澄清需要考虑深拷贝备份。如果取而代之的是复制浅层的、可变的引用,那么回滚特性将陷入一片混乱。我还要补充(进一步补充上面的评论)try/catch/finally本质上不是原子的。我在答案中添加了一个例子。