Reputation: 7547
I am saving user's uploaded file on the disk and just storing filename in database. I want to write a code such that if record is inserted and file is saved on disk then only it should commit. If record is created in DB but file could not be saved due to permission issue etc I want the whole transaction to be rolled back. Obviously this cannot be done using SqlTransaction
How should I ensure this type of integrity of datda?
Upvotes: 1
Views: 134
Reputation: 13246
I usually do one of the following for non-transactional tasks that need some management (or, in your case, something that is difficult to include in a transaction):
1) Perform the non-transactional task last. If it fails then there should be nothing to worry about since the transaction is rolled back, e.g.: - e-mail not sent - file not saved
2) Use some process/saga that performs a type of "two-phase commit". Maybe an entry outside of a transaction in a table that indicates that your file saving task has to be verified. Then try your "actual" bit in your transaction (save record, save file). Then another scheduled/ad-hoc service can check whether the task completed and clean up if it did not.
3) Along the lines of (2): first store the data in a temporary state (more-or-less the way a write-ahead log works). If the state is OK you know the data is all there and you can continue and mark you record as completed or move it to its permanent home. Another scheduled/ad-hoc task can clean up any temporary data if it has expired.
Upvotes: 1
Reputation: 7757
Windows Vista and above support Transactional NTFS, which allows you to enlist filesystem operations in a transaction as you require. Unfortunately, the .NET Framework does not directly support this functionality, so you have to either call unmanaged APIs directly via P/Invoke or utilize a third-party managed wrapper library like Transactional NTFS (TxF) .NET:
I've not used this myself but after doing some searching this one looks to be the most usable.
Upvotes: 1