我想在java中实现类似事务的功能。我想做' n '操作,比如更新数据库的操作,插入队列的操作,更新另一种数据结构的操作等,所有这些操作都应该表现为一个事务,即,如果它成功,所有的操作应该成功完成,否则,如果一个失败,一切都应该失败。蛮力方法之一是编写 try-catch 块并恢复 catch 块中的所有操作。解决此类问题的任何指示?是否有任何模式或库可以实现这一目标?
5 回答
不,你想要 JTA。
蛮力的方法是使用 JDBC 并自己管理提交和回滚。
最简单的方法是使用 Spring 或 EJB3.1 和声明性事务。
我认为您正在寻找的模式是Command。
交易行为
与撤消类似,数据库引擎或软件安装程序可能会保留已执行或将要执行的操作列表。如果其中一个失败,所有其他都可以恢复或丢弃(通常称为回滚)。例如,如果必须更新相互引用的两个数据库表,而第二次更新失败,则可以回滚事务,从而使第一个表现在不包含无效引用。
我已经结合了命令和复合设计模式来做到这一点。Transaction 类是抽象的,包含 begin() 和 rollback() 方法。CompositeTransaction 派生自 Transaction 并存储 Transaction 对象的列表。对于需要被视为原子事务的每组操作,创建 CompositeTransaction 的子类并将您的 Transaction 类添加到其中。在此处查看 CompositeTransaction:
http://hillside.net/plop/plop99/proceedings/grand/plop_99_transaction_patterns.pdf
访问者模式效果很好。此外,您需要确保在正确的时间发出提交。如果您等到插入/更新集完成,然后发出提交,您描述的行为应该是自动的。
听起来你可能需要对你的 sql 语句类进行一些重构,以确保你可以在没有隐含提交的情况下发出一些语句。
这只是关于如何实现这一点的逻辑。
根据需要为每个事务编写一个方法。可能它会拥有所有资源。像 jdbc 事务将有连接对象和查询作为要求,文件操作如果有文件路径,等等。
因此,对于 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...
}
}
谢谢。