Я нашел способ реализовать транзакцию, но не знаю подводных камней этого метода. Ключевым элементом является truncate syscall, который позволит нам реализовать логику отката. Вот псевдокод:
file1Pos = file1.tell()
file2Pos = file2.tell()
err = file1.write(bytes1)
if err != nil {
// rollback to previous position
file1.truncate(file1Pos)
// The file offset is not changed after truncation
file1.seek(file1Pos, SEEK_SET)
}
err = file2.write(bytes2)
if err != nil {
file1.truncate(file1Pos)
file1.seek(file1Pos, SEEK_SET)
file2.truncate(file2Pos)
file2.seek(file2Pos, SEEK_SET)
}