diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
@@ -517,8 +517,8 @@
 }
 
 typedef bool ShouldBeInTransaction;
-typedef std::pair<std::function<bool(sqlite3 *)>, ShouldBeInTransaction>
-    SQLiteMigration;
+typedef std::function<bool(sqlite3 *)> MigrateFunction;
+typedef std::pair<MigrateFunction, ShouldBeInTransaction> SQLiteMigration;
 std::vector<std::pair<uint, SQLiteMigration>> migrations{
     {{1, {create_drafts_table, true}},
      {2, {rename_threadID_to_key, true}},
@@ -536,6 +536,59 @@
      {24, {add_not_null_constraint_to_drafts, true}},
      {25, {add_not_null_constraint_to_metadata, true}}}};
 
+enum class MigrationResult { SUCCESS, FAILURE, NOT_APPLIED };
+
+MigrationResult applyMigrationWithTransaction(
+    sqlite3 *db,
+    const MigrateFunction &migrate,
+    int index) {
+  sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
+  auto db_version = get_database_version(db);
+  if (index <= db_version) {
+    sqlite3_exec(db, "ROLLBACK;", nullptr, nullptr, nullptr);
+    return MigrationResult::NOT_APPLIED;
+  }
+  auto rc = migrate(db);
+  if (!rc) {
+    sqlite3_exec(db, "ROLLBACK;", nullptr, nullptr, nullptr);
+    return MigrationResult::FAILURE;
+  }
+  auto database_version_set = set_database_version(db, index);
+  if (!database_version_set) {
+    sqlite3_exec(db, "ROLLBACK;", nullptr, nullptr, nullptr);
+    return MigrationResult::FAILURE;
+  }
+  sqlite3_exec(db, "END TRANSACTION;", nullptr, nullptr, nullptr);
+  return MigrationResult::SUCCESS;
+}
+
+MigrationResult applyMigrationWithoutTransaction(
+    sqlite3 *db,
+    const MigrateFunction &migrate,
+    int index) {
+  auto db_version = get_database_version(db);
+  if (index <= db_version) {
+    return MigrationResult::NOT_APPLIED;
+  }
+  auto rc = migrate(db);
+  if (!rc) {
+    return MigrationResult::FAILURE;
+  }
+  sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
+  auto inner_db_version = get_database_version(db);
+  if (index <= inner_db_version) {
+    sqlite3_exec(db, "ROLLBACK;", nullptr, nullptr, nullptr);
+    return MigrationResult::NOT_APPLIED;
+  }
+  auto database_version_set = set_database_version(db, index);
+  if (!database_version_set) {
+    sqlite3_exec(db, "ROLLBACK;", nullptr, nullptr, nullptr);
+    return MigrationResult::FAILURE;
+  }
+  sqlite3_exec(db, "END TRANSACTION;", nullptr, nullptr, nullptr);
+  return MigrationResult::SUCCESS;
+}
+
 void SQLiteQueryExecutor::migrate() const {
   validate_encryption();
 
@@ -554,31 +607,30 @@
   Logger::log(version_msg.str());
 
   for (const auto &[idx, migration] : migrations) {
-    if (idx <= db_version) {
-      continue;
-    }
     const auto &[applyMigration, shouldBeInTransaction] = migration;
 
-    std::stringstream migration_msg;
-
+    MigrationResult migrationResult;
     if (shouldBeInTransaction) {
-      sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
+      migrationResult = applyMigrationWithTransaction(db, applyMigration, idx);
+    } else {
+      migrationResult =
+          applyMigrationWithoutTransaction(db, applyMigration, idx);
     }
 
-    auto rc = applyMigration(db);
-    if (!rc) {
+    if (migrationResult == MigrationResult::NOT_APPLIED) {
+      continue;
+    }
+
+    std::stringstream migration_msg;
+    if (migrationResult == MigrationResult::FAILURE) {
       migration_msg << "migration " << idx << " failed." << std::endl;
       Logger::log(migration_msg.str());
       break;
     }
-
-    set_database_version(db, idx);
-
-    if (shouldBeInTransaction) {
-      sqlite3_exec(db, "END TRANSACTION;", nullptr, nullptr, nullptr);
+    if (migrationResult == MigrationResult::SUCCESS) {
+      migration_msg << "migration " << idx << " succeeded." << std::endl;
+      Logger::log(migration_msg.str());
     }
-    migration_msg << "migration " << idx << " succeeded." << std::endl;
-    Logger::log(migration_msg.str());
   }
 
   sqlite3_close(db);