我必须编写一些方法来将值更改为数据库并在文件系统上进行一些操作。 所以我必须做出这一步骤:
Updating
字段设置为true
到数据库中。它用于避免访问与此值链接的文件系统和数据库信息(例如车队)Updating
设置为false 您可以想象我必须管理错误并启动回滚过程以恢复数据库和文件系统。 我对如何编写我的方法有一些疑问。我有:
JpaRepository
并使用方法名称创建查询的存储库接口,如果他们写入数据库,则使用@Query
注释@Transactional
(否则我收到错误)@Transactional
从其他类我调用服务方法来使用数据库,但如果我调用其中一些方法,我会将每个值写入数据库,因此不可能抛出回滚,或者我错了? 步骤1必须立即写入数据库而不是其他更改应该使用@Transactional属性,但只是将@Transactional添加到我的方法就足够了?对于文件系统回滚,我创建所有子文件夹的备份,并在出现错误时将其还原。 例如:
@Transactional(rollbackFor=FileSystemException.class)
private void changeDisplacement(int idApplication, int idDisplacement){
applicationServices.setUpdating(true); //this has be to write immediatly into database so that the other methods can stop using this application
Application application = applicationServices.getId(idApplication);
application.setDisplacement(displacementServices.getId(idDisplacement));
//OTHER OPERATIONS ON DIFFERENT TABLES
//OPERATIONS ON FILE SYSTEM CATCHING ALL EXCEPTION WITH TRY-CATCH AND IN THE CATCH RESTORE FILESYSTEM AND THROW FileSystemException to start database rollback
//In the finally clause use applicationServices.setUpdating(false)
}
是否可以使用此逻辑或此处@Transactional
字段有误?
谢谢
答案 0 :(得分:1)
这里有很多问题,其中一些很难掌握,这里有一些输入。如果你有这个:
@Transactional(rollbackFor=FileSystemException.class)
private void changeDisplacement(int idApplication, int idDisplacement){
applicationServices.setUpdating(true);
仅当@Transactional
完成时,该标志才会到达数据库。更改将保留在hibernate上下文中,直到@Transactionl
方法结束。
因此,当您执行changeDisplacement
并且其他人来并读取该标志时 - 它将看到错误(因为您尚未将其写入数据库)。您可以通过READ_UNCOMMITTED
获取它,但如果您允许,则由您的应用程序决定。
你可以使用REQUIRES_NEW
的方法,并在那里将该标志设置为true,并且如果还原更新,则标记为。
通常更新数据库和文件系统并不容易(保持同步)。我之前完成它的方式(可能是更好的选项)是注册事件(一旦创建了正确的数据库),然后写入文件系统。
答案 1 :(得分:1)
@Transactional
在这里没问题。唯一需要设置applicationServices.setUpdating
到REQUIRES_NEW
的传播,以便它可以单独提交:
public class ApplicationServices {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void setUpdating(boolean b) {
// update DB here
}
}
如果是异常,只要您在finally块中调用setUpdating
,它仍会更新数据库。