If control flow gets to the point of calling Commit()
on the guard reference, all is well, assuming the Commit method does not throw. Needless to
say, you should code your Commit() in such a way that the Database remains in a valid state.
However, if your code inside the guarded block throws an exception, the Dispose method in
the RollbackHelper will diligently roll back your database.
No matter what happens, the Dispose method will be called on the RollbackHelper
instance, thanks to the Using block. If you forget the Using block, the finalizer for the
RollbackHelper will not be able to do anything for you, since finalization of objects goes in
random order, and the Database referenced by the RollbackHelper could be finalized prior to
the RollbackHelper instance. To help you find the places where you omitted Using, you can
code an assertion into the helper object. Since the whole use of this pattern hinges on the
Using block, for the sake of discussion, let??™s assume you didn??™t forget it.
Once execution is safely inside the Dispose method, and it got there via a call to Dispose()
rather than through the finalizer, it simply checks the committed flag, and if it??™s not set, it calls
Rollback() on the Database instance. That??™s all there is to it.
Pages:
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279