Eliminating duplicate transaction code

The Apply and Run methods duplicated the block of code that cached the
current transaction, created a new transaction if necessary, did the
operation, and closed the newly created transaction, if one was created.

Pulled logic out into a separate abstracting class, and putting the
different logic into separate subclasses. 3 new classes added in total.