Fix race conditions when multiple processes initialize a Realm file at the same time

Main change here is to unconditionally start a write transaction on schema init, push the version check inside that write transaction, and roll it back if it turns out that no changes are needed, to avoid having two processes both decide that they need to initialize things (in the single-process case this was previously prevented via an `@synchronized` block). I *think* the double-init would have worked out okay other than a spurious change notification, but I'm much less confident in that than I am in this working correctly.

There's three functional changes:

1. Dynamic realms are now cached, as we concluded that there was no reason for them not to be and it simplifies the code a bit

2. Explicitly calling migrateRealmAtPath: will create any missing tables even if the schema version matches. Main point is to push the schema version check into the write transaction to avoid a spurious migration, but it also just seems like the right behavior.

3. Exceptions during migrations cancel the write rather than committing.

@alazier