What happens to in-flight TxF writes when a Windows 8 transaction hits its timeout?
0 reputation · 11 Sept 2020, 04:28 UTC
0 reputation · 11 Sept 2020, 04:28 UTC
I'm designing a file-write component for a Windows 8 desktop application that uses Transactional NTFS (TxF) via CreateFileTransacted, CommitTransaction, and RollbackTransaction. The goal is to retry a failed write inside the same transaction so a transient I/O error never produces duplicated data in the target file.
The part I cannot pin down is the transaction timeout. My understanding is that a transaction left open too long (around the default 60-second window) may be aborted automatically by the system. If that happens between a failed write and my retry, I need to know what state the file and the transaction handle are actually in, because my retry logic depends on the transaction still being active.
Assume a local NTFS volume on Windows 8 (TxF is unavailable on ReFS and network shares), and that the application holds a valid transaction handle throughout.
When the system aborts a TxF transaction for exceeding its timeout, is any portion of the uncommitted write ever visible in the file, or is rollback guaranteed to be complete?
Is the timeout value configurable per transaction or system-wide, and how can the application detect that an abort occurred rather than discovering it only when CommitTransaction fails?
31275 reputation · 11 Sept 2020, 12:35 UTC
When a TxF transaction exceeds its timeout (roughly 60 seconds by default), the Windows Transaction Manager aborts it, and rollback is complete. No portion of your uncommitted writes ever becomes visible in the target file — not to other readers, and not after the abort. The file reverts to its exact pre-transaction state. Atomicity is the entire point of TxF, and a timeout-triggered abort goes through the same rollback path as an explicit RollbackTransaction call.
The practical consequence for your retry design is the opposite of what you hoped: you cannot retry a failed write inside the same transaction after a timeout abort, because the transaction no longer exists. Your retry logic must detect the abort, start a brand-new transaction, and redo the write from scratch.
Your transaction handle remains a valid handle object, but the transaction it refers to is gone. Any transacted file handles created with CreateFileTransacted against that transaction are similarly orphaned. The next operation you attempt — whether a write or CommitTransaction — will fail with a transaction-related error such as ERROR_TRANSACTION_NOT_FOUND or a code indicating the transaction is no longer active. Always check GetLastError() after every transacted I/O call, not just at commit time, so you learn about the abort at the first failing operation instead of at commit.
Not through the standard Win32 TxF surface. CreateTransaction accepts a timeout parameter in milliseconds, and passing 0 selects the system default — but the system can still abort a transaction for other reasons (resource pressure, log issues), so treating the timeout as a hard guarantee is unsafe either way. Design as if any transaction can be aborted at any time.
There is no supported API to poll a transaction's liveness. Detection is reactive:
GetLastError() on every transacted write and on CommitTransaction.RollbackTransaction defensively (it will simply fail harmlessly if the transaction is already gone), then open a new transaction and retry the whole unit of work.Because the ~60-second figure is a guideline that can vary with build and load, confirm on your target Windows 8 machines:
CommitTransaction.TxF is effectively deprecated in later Windows versions and unsupported on ReFS and network shares. If this component has a long life ahead of it, consider whether a write-temp-file-then-atomic-rename pattern (e.g., ReplaceFile) meets your durability goals with a supported API. That decision hinges on one detail you didn't mention: whether you need multi-file atomicity. TxF's real advantage is atomic updates across several files; for a single file, rename-based replacement is simpler and future-proof.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.