Java 中类似事务的编程

发布于 2024-10-27 10:40:46 字数 209 浏览 5 评论 0原文

我想用java实现类似事务的功能。我想要执行“n”操作,例如:一项更新数据库的操作、一项插入队列的操作、一项更新另一数据结构的操作等,所有这些操作都应表现为一个事务,即,如果成功,则所有操作都应该成功完成,否则,如果其中一个失败,则一切都应该失败。一种强力方法是编写 try-catch 块并恢复 catch 块中的所有操作。有解决此类问题的建议吗?有没有任何模式或库可以实现这一目标?

I want to achieve transaction like functionality in java. I want to do `n' operations like- one operation to update database, one to insert in a queue, one operation to update another data structure etc., All these operations should behave as one transaction, i.e., if it succeeds, all the operations should be successfully done, otherwise, if one fails, everything should fail. One of the brute force approach is to write try-catch blocks and revert all the operations in catch blocks. Any pointers in solving these type of problems? Is there any pattern or library for achieving this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谎言月老 2024-11-03 10:40:47

我认为您正在寻找的模式是 Command

交易行为

与撤消类似,数据库引擎或软件安装程序可以保留已执行或将要执行的操作的列表。如果其中之一失败,所有其他都可以恢复或丢弃(通常称为回滚)。例如,如果必须更新两个相互引用的数据库表,而第二次更新失败,则可以回滚事务,以便第一个表现在不包含无效引用。

I think the pattern you are looking for is Command.

Transactional behavior

Similar to undo, a database engine or software installer may keep a list of operations that have been or will be performed. Should one of them fail, all others can be reverted or discarded (usually called rollback). For example, if two database tables which refer to each other must be updated, and the second update fails, the transaction can be rolled back, so that the first table does not now contain an invalid reference.

清音悠歌 2024-11-03 10:40:47

我结合了命令设计模式和复合设计模式来完成此任务。 Transaction 类是抽象的,包含 begin() 和 begin() 。 rollback() 方法。 CompositeTransaction 派生自 Transaction,并存储 Transaction 对象的列表。对于需要被视为原子事务的每组操作,创建 CompositeTransaction 的子类并向其中添加事务类。请参阅此处的 CompositeTransaction:

http://hillside.net/plop/plop99/proceedings/盛大/plop_99_transaction_patterns.pdf

I've done this with a combination of the Command and Composite Design Patterns. The Transaction class is abstract and contains begin() & rollback() methods. The CompositeTransaction is derived from Transaction and stores a list of Transaction objects. For each group of operations that need to be treated as an atomic transaction, create a subclass of the CompositeTransaction and add your Transaction classes to this. see the CompositeTransaction here:

http://hillside.net/plop/plop99/proceedings/grand/plop_99_transaction_patterns.pdf

柒七 2024-11-03 10:40:47

访客模式效果很好。
此外,您需要确保在正确的时间发出提交。如果您等到插入/更新集完成,然后发出提交,您所描述的行为应该是自动的。

听起来也许您需要对 sql 语句类进行一些重构,以确保您可以在没有隐含提交的情况下发出一些语句。

a visitor pattern works well.
also, you will need to make sure you issue the commit at the right time. if you wait until the set of inserts/updates in complete, then issue commit, your described behavior should be automatic.

sounds like maybe you need a little refactor of your sql staement class to make sure you can issue some statements without the implied commit.

小伙你站住 2024-11-03 10:40:47

这只是关于如何实现这一目标的逻辑。

根据需要为每笔交易编写一个方法。也许它会拥有所有的资源。像jdbc事务会有Connection对象和查询作为要求,文件操作如果有的话会有文件路径,等等。

因此对于 5 笔交易,将有 5 种不同的方法。您也可以通过单一方法来实现它,但这只是为了简单起见。

例如

method1(...) throws Exception {
    ...
    // if any exception occurs then control will be passed to caller of this
    // method
    throw new Exception("1"); // write method number
}

,然后编写一个方法为(以下只是一个模板):

public long/void transaction(...) throws Exception
{
    try {
        this.method1(...);
        this.method2(...);
        this.method3(...);
    } catch (Exception e) {
        // get that number in a exception message
        // and try to undo all operations numbers less than above number.
        // e.g. if that transaction method is any database transaction then
        // try to rollback it.
        // if it is creation of any file say log file then delete it
        // now further logic depends on what the transaction was and how to
        // undo it...
    }
}

谢谢。

This is just a logic about how can you achieve this.

Write a method for each transaction as you want. Probably it would have all its resources. Like jdbc transaction will have Connection object and query as a requirement, file operation if any will have file path, and so on.

So for 5 transaction, there will be 5 different methods. You can achieve it in a single method as well but this is just for simplicity.

e.g.

method1(...) throws Exception {
    ...
    // if any exception occurs then control will be passed to caller of this
    // method
    throw new Exception("1"); // write method number
}

Then write a method as (following is just a template):

public long/void transaction(...) throws Exception
{
    try {
        this.method1(...);
        this.method2(...);
        this.method3(...);
    } catch (Exception e) {
        // get that number in a exception message
        // and try to undo all operations numbers less than above number.
        // e.g. if that transaction method is any database transaction then
        // try to rollback it.
        // if it is creation of any file say log file then delete it
        // now further logic depends on what the transaction was and how to
        // undo it...
    }
}

Thanks.

jJeQQOZ5 2024-11-03 10:40:46

不,你想要 JTA。

强力方法是使用 JDBC 并自行管理提交和回滚。

最简单的方法是使用 Spring 或 EJB3.1 和声明性事务。

Nope, you want JTA.

The brute force way would be to use JDBC and manage commit and rollback yourself.

The easiest way of all would be to use Spring or EJB3.1 and declarative transactions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文