This is inspired by [1].
Quite frankly, I don't know why filesystems don't provide these things.
I have read that Windows has a transactional API, but they've actually deprecated it! [2] They say it's because few programs use it.
I mean, sure, that might be true, but I bet it's really important for those programs that do use it.
Bonus question: why does Windows hide its equivalent of `openat()` in the NT API? [3] Rust code seems to claim its fundamental to the NT kernel [4], so why is it not exposed?
[1]: https://news.ycombinator.com/item?id=32190032
[2]: https://docs.microsoft.com/en-us/windows/win32/fileio/deprec...
[3]: https://docs.microsoft.com/en-us/windows/win32/api/winternl/...
[4]: https://github.com/rust-lang/rust/blob/1c63ec48b8cbf553d291a...
what sort of semantics would you want out of the transaction? atomicity? isolation? durability? how should concurrency behave? should there be a mvcc implementation?
linux provides atomic writes up to 4k. moves on the same fs are also atomic.
fsync ensures writes are durable and written to disk (allegedly[0])
file advisory locks can be used to ensure mutual exclusion. or memory mapping in the file to shared memory and allocating a mutex in it (libapr provides a few options for interprocess mutual exclusion)
...but in reality, if you need transactional semantics, you're really just better off using a database. because the database developers will have a much better idea of the nuances that applications need from transactional semantics than the kernel devs will.
and if you want your program that requires transactional semantics to be portable, major database vendors have already dealt with inconsistencies across multiple major operating systems. because of that the database gives one system to handle transactions, versus pushing the portability concerns onto each individual application.
[0] https://news.ycombinator.com/item?id=19119991