Вы можете использовать @Transactional Spring для этого.
Вот пример кода, который я пробовал. Он выполняет операцию базы данных с последующей файловой операцией, в моем примере я пытаюсь создать файл. Сначала я создаю файл перед выполнением операции с базой данных и использую TransactionSynchronizationAdapter
, чтобы убедиться, что транзакция завершена перед фиксацией.
Код:
@Autowired
private UserService userService;
@Transactional
public String doFileOperation() {
File testFile = new File("C:\\test.txt");
TxnListener transactionListener = new TxnListener(testFile);
TransactionSynchronizationManager.registerSynchronization(transactionListener);
// DB Operation
userService.addUser();
// File Operation
List<String> lines = Arrays.asList("1st line", "2nd line");
try {
Files.write(Paths.get(testFile.getPath()),
lines,
StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
public class TxnListener extends TransactionSynchronizationAdapter {
private File outputFile;
public TxnListener(File outputFile) {
this.outputFile = outputFile;
}
@Override
public void afterCompletion(int status) {
if (STATUS_COMMITTED != status) {
if (outputFile.exists()) {
if (!outputFile.delete()) {
System.out.println("Could not delete File" + outputFile.getPath() + " after failed transaction");
}
}
}
}
}
В случае возникновения исключительной ситуации во время операции с базой данных будет вызван afterCompletion
и файл будет удален.
Таким образом, вы можете поддерживать атомарность операции.