MigrationRunner
Runs one migration, by whichever of the two paths it asked for.
They differ in where the history row sits relative to the transaction. A transactional migration writes its row inside the transaction that did the work, so a failure takes both. One without a transaction writes the row first as MigrationState.RUNNING and closes it off afterwards, because a failure there really does leave the database part-way.