So you'd think a system at this core level should be well-designed, right? Wrong! There are a number of faults in the architecture of this system, but by far the most blatant is a pattern called "Exception? Won't happen!" It's the most pernicious of them all because it results in a number of complex, hard-to-debug data defects:
- Data partially processed, or processed incorrectly and has to be manually rolled back.
- Files that are generated, but not uploaded properly.
- Multiple day's worth of data just "missing" from generated files.
Try PrepareData() Catch ex As Exception LogException(ex) End Try Try GenerateFile() Catch ex As Exception LogException(ex) End Try Try ArchiveData() Catch ex As Exception LogException(ex) End Try Try UploadFile() Catch ex As Exception LogException(ex) End Try
At first glance you might think there's nothing wrong - the developer has wisely adding exception handling and logging to the system to make sure errors can be detected and reviewed. The problem comes if something does indeed fail. For example, what happens if "UploadFile()" process fails? Well, the first three processes will have already finished and been committed. The data has been archived permanently, but the generated file never got uploaded to the 3rd-party network. That means they will never receive the data, and we will never send it again because it's been marked "complete"! Apparently the developer assumed that "nothing could go wrong".
Resolving this defect can be a little time-consuming, but definitely worth it. I generally approach it this way:
- Wrap all sub-steps in some sort of transaction.
- Pass the same transaction to each method.
- If the entire process (work unit) is successful, commit the transaction at the end.
- If anything fails on any step, roll the entire process back, including deleting any temp files that were partially created.
- Everything is left in a consistent state then for another try in the next processing cycle.
Happy programming!
No comments:
Post a Comment