Java атомарное перемещение файлов дублирует файлы при отключении питания - PullRequest
1 голос
/ 06 ноября 2019

Java-приложение перемещает атомарный файл следующим образом:

Path source = Paths.get(fullFileName + ".tmp");
Path target = Paths.get(fullFileName);

Files.delete(target);
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);

Исходный файл существует или создается до перемещения. Источник и цель расположены в одном месте и имеют одинаковое значение FileSystemProvider. С опцией атомарного перемещения я ожидаю, что в любой момент в системе будет присутствовать только один из файлов или будет сгенерировано исключение.

Тем не менее, когда происходит сбой питания, я нахожу исходные и целевые файлы надиск с тем же содержанием. Я не исключаю другие потенциальные проблемы, но до сих пор он надежно оставлял дубликаты.

File system: EXT4
Storage type: eMMC Flash
CPU Architecture: ARM
OS: Debian 4.9.11-02300-ga1ac172-dirty #2 SMP PREEMPT Mon Apr 23 12:58:56 CDT 2018 armv7l GNU/Linux

Я что-то упустил? Означает ли это, что атомный ход не поддерживается?

1 Ответ

2 голосов
/ 06 ноября 2019

Я думаю, вы неправильно понимаете, что такое атомный ход:

  1. Только ход атомный. Остальная часть обработки вашего файла не выполняется.
  2. Гарантии атомарности POSIX предназначены для работающего программного обеспечения, а не для ситуации с потерей питания.

Рассмотрим ваш код:

void foo(String fullFileName) {
    // 1
    Path source = Paths.get(fullFileName + ".tmp");
    // 2
    Path target = Paths.get(fullFileName);
    // 3
    Files.delete(target);
    // 4
    Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
    // 5
}

Если программа прерывается на 1, 2 или 3, то вы оставляете оба файла в системе. Ваш атомный ход еще не был задействован, поэтому ничто из того, что он там сделал, ни на что не повлияет.

Если программа будет прервана на 4 или 5, у вас будет только один файл, но если питание будет прервано, больше нет никаких гарантий относительно состояния файловой системы, когда она возвращается.

Похоже, вам нужна база данных с поддержкой транзакций.

...