protected virtual async Task Apply(IUpgrade upgrade) { _log.LogDebug("Upgrade to {0}", upgrade.UpgradeTo); using (var session = await _db.Client.StartSessionAsync()) { if (_isTransactionsAvailable) { session.StartTransaction(); } try { await upgrade.Apply(session, _db, _logFactory.CreateLogger(upgrade.GetType())); await _tracker.TrackSuccessUpgrade(session, upgrade.UpgradeTo); if (_isTransactionsAvailable) { await session.CommitTransactionAsync(); } } catch (Exception ex) { if (_isTransactionsAvailable) { _log.LogError("Upgrade to {0} failed, rollback the transaction...", upgrade.UpgradeTo); await session.AbortTransactionAsync(); } else { _log.LogCritical("Upgrade to {0} failed & transactions are not supported. DB may be inconsistent.", upgrade.UpgradeTo); } throw new MigrationException($"Upgrade to ver {upgrade.UpgradeTo} failed.", ex); } } MigrationState = await _tracker.GetState(); _log.LogDebug("Upgrade success, current version is {0}", upgrade.UpgradeTo); }