Spring 事务白衣几个操作和回滚
Spring transaction whit several operations and rollback
我必须编写一些方法来将值更改为数据库并在文件系统上进行一些操作。
所以我必须执行以下步骤:
- 将布尔
Updating
字段设置为 true
到数据库中。它用于避免访问与此值链接的文件系统和数据库信息(例如车队)
- 对数据库进行一些操作。例如更改日期、名称、值或其他字段。这些更改会影响更多数据库表。
- 更改文件系统和数据库
- 将布尔值
Updating
设置为 false
如您所想,我必须管理错误并启动回滚程序以恢复数据库和文件系统。
我对如何编写我的方法有一些疑问。我有:
- 实体
- 存储库接口扩展
JpaRepository
并从方法名称和 @Query
创建查询,如果它们写入数据库(否则我收到错误)@Transactional
注释
- 服务接口
- 包含对数据库进行简单更改的所有方法的服务实现。此 class 注释为
@Transactional
从其他 classes 我调用服务方法来使用数据库但是如果我调用其中一些方法我将每个值写入数据库所以不可能抛出回滚,或者我错了?
第 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
字段错了?
谢谢
这里有多个问题,其中一些很难掌握,这里有一点输入。当你有这个:
@Transactional(rollbackFor=FileSystemException.class)
private void changeDisplacement(int idApplication, int idDisplacement){
applicationServices.setUpdating(true);
只有当 @Transactional
完成时,该标志才会命中数据库。更改保留在休眠上下文中,直到 @Transactionl
方法结束。
因此,当您执行 changeDisplacement
时,其他人会来读取该标志 - 它会看到 false(因为您尚未将其写入数据库)。您可以通过 READ_UNCOMMITTED
获取它,但是否允许这样做取决于您的应用程序。
您可以使用 REQUIRES_NEW
的方法并将该标志设置为 true 并在恢复时更新该标志。
通常同时更新数据库和文件系统并不容易(保持同步)。我之前完成的方法(可能是更好的选择)是注册事件(一旦创建了正确的数据库)然后写入文件系统。
@Transactional
就可以了。唯一的事情是你需要将 applicationServices.setUpdating
的传播设置为 REQUIRES_NEW
以便它单独提交:
public class ApplicationServices {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void setUpdating(boolean b) {
// update DB here
}
}
在异常情况下,只要您在 finally 块中调用 setUpdating
,它仍会更新数据库。
我必须编写一些方法来将值更改为数据库并在文件系统上进行一些操作。 所以我必须执行以下步骤:
- 将布尔
Updating
字段设置为true
到数据库中。它用于避免访问与此值链接的文件系统和数据库信息(例如车队) - 对数据库进行一些操作。例如更改日期、名称、值或其他字段。这些更改会影响更多数据库表。
- 更改文件系统和数据库
- 将布尔值
Updating
设置为 false
如您所想,我必须管理错误并启动回滚程序以恢复数据库和文件系统。 我对如何编写我的方法有一些疑问。我有:
- 实体
- 存储库接口扩展
JpaRepository
并从方法名称和@Query
创建查询,如果它们写入数据库(否则我收到错误)@Transactional
注释 - 服务接口
- 包含对数据库进行简单更改的所有方法的服务实现。此 class 注释为
@Transactional
从其他 classes 我调用服务方法来使用数据库但是如果我调用其中一些方法我将每个值写入数据库所以不可能抛出回滚,或者我错了? 第 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
字段错了?
谢谢
这里有多个问题,其中一些很难掌握,这里有一点输入。当你有这个:
@Transactional(rollbackFor=FileSystemException.class)
private void changeDisplacement(int idApplication, int idDisplacement){
applicationServices.setUpdating(true);
只有当 @Transactional
完成时,该标志才会命中数据库。更改保留在休眠上下文中,直到 @Transactionl
方法结束。
因此,当您执行 changeDisplacement
时,其他人会来读取该标志 - 它会看到 false(因为您尚未将其写入数据库)。您可以通过 READ_UNCOMMITTED
获取它,但是否允许这样做取决于您的应用程序。
您可以使用 REQUIRES_NEW
的方法并将该标志设置为 true 并在恢复时更新该标志。
通常同时更新数据库和文件系统并不容易(保持同步)。我之前完成的方法(可能是更好的选择)是注册事件(一旦创建了正确的数据库)然后写入文件系统。
@Transactional
就可以了。唯一的事情是你需要将 applicationServices.setUpdating
的传播设置为 REQUIRES_NEW
以便它单独提交:
public class ApplicationServices {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void setUpdating(boolean b) {
// update DB here
}
}
在异常情况下,只要您在 finally 块中调用 setUpdating
,它仍会更新数据库。