gpt4 book ai didi

java - 事件观察者方法调用服务方法?

转载 作者:太空宇宙 更新时间:2023-11-04 11:18:32 25 4
gpt4 key购买 nike

好的,我想要完成的任务如下:

在java enterprise bean中,我想将文件移动到不同的目录,除非数据库操作失败(即,我想将文件的正确位置存储在数据库中。现在,如果事务中出现问题并且回滚,如果我已经移动了文件,我的数据库将指向文件的错误位置。不好。)。

我尝试使用事务阶段 AFTER_SUCCESS 来移动文件,并使用观察方法来触发事件。到目前为止,一切都很好。但文件移动也可能失败(也许我无权访问目标目录或类似的东西),我也想将该失败写入数据库。不幸的是,观察者方法似乎没有为我提供事务,并且我的方法调用失败。

从观察方法调用服务方法的想法是不好的吗?还是我做错了?

最佳答案

通常,您应该首先使用事务性资源,然后再使用非事务性资源。原因是您可以回滚事务性资源,但无法回滚非事务性资源。

我的意思是:如果您能够更新数据库中的行,然后尝试移动文件但失败,您可以安全地回滚数据库更新。但是,如果您移动文件并且成功,但由于某种原因无法更新数据库 - 您无法回滚移动的文件。

在您的特定情况下,我建议不要实际移动文件,而是复制它。这样在数据库中您将始终拥有新副本的实际位置。在不同的线程中,您可以以某种方式删除旧副本。您需要使用副本,因为在移动实际文件时可能会引发 IOException ,并且当您回滚数据库中的事务时,您最终会得到错误的旧位置。尝试使用这种方法(使用 EJB 容器管理事务;您可以安全地找到该方法的 Spring 变体):

@TransactionAttribute(REQUIRED)
void move(String newLocation, int fileId) throws CouldNotMoveException, DatabaseException {
try {
database.updateFileLocation(fileId, newLocation);
} catch (Exception exc) {
throw new DatabaseException(exc);
}
try {
file.copyFile(fileId, newLocation);
} catch (IOException exc) {
throw new CouldNotMoveException(exc);
}
}

您将需要创建这样的异常,以便回滚您的事务(或者仅使用 RuntimeException - 检查容器上有关对异常和回滚策略使用react的文档):

@ApplicationException(rollback = true)
public class DatabaseException extends Exception {
// omited
}

@ApplicationException(rollback = true)
public class CouldNotMoveException extends Exception {
// omited
}

在这里,您的客户端代码可以对 CouldNotMoveException 使用react,并在数据库中写入错误的移动,这样您就可以满足您的要求。

关于java - 事件观察者方法调用服务方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45182420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com