diff --git a/core/modules/mysql/src/Hook/MysqlRequirements.php b/core/modules/mysql/src/Hook/MysqlRequirements.php
index c3dfb10ca434cd096fa0db34203e88f578af93f0..55a3e144bbafafb6f52a3c781af0c0f40cbb9836 100644
--- a/core/modules/mysql/src/Hook/MysqlRequirements.php
+++ b/core/modules/mysql/src/Hook/MysqlRequirements.php
@@ -5,16 +5,16 @@
 namespace Drupal\mysql\Hook;
 
 use Drupal\Core\Database\Database;
-use Drupal\Core\Extension\Requirement\RequirementSeverity;
 use Drupal\Core\Hook\Attribute\Hook;
-use Drupal\Core\Render\Markup;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\mysql\RequirementsTrait;
 
 /**
  * Requirements for the MySQL module.
  */
 class MysqlRequirements {
 
+  use RequirementsTrait;
   use StringTranslationTrait;
 
   /**
@@ -22,65 +22,17 @@ class MysqlRequirements {
    */
   #[Hook('runtime_requirements')]
   public function runtime(): array {
-    $requirements = [];
-    // Test with MySql databases.
-    if (Database::isActiveConnection()) {
-      $connection = Database::getConnection();
-      // Only show requirements when MySQL is the default database connection.
-      if (!($connection->driver() === 'mysql' && $connection->getProvider() === 'mysql')) {
-        return [];
-      }
-
-      $query = $connection->isMariaDb() ? 'SELECT @@SESSION.tx_isolation' : 'SELECT @@SESSION.transaction_isolation';
-
-      $isolation_level = $connection->query($query)->fetchField();
-
-      $tables_missing_primary_key = [];
-      $tables = $connection->schema()->findTables('%');
-      foreach ($tables as $table) {
-        $primary_key_column = Database::getConnection()->query("SHOW KEYS FROM {" . $table . "} WHERE Key_name = 'PRIMARY'")->fetchAllAssoc('Column_name');
-        if (empty($primary_key_column)) {
-          $tables_missing_primary_key[] = $table;
-        }
-      }
-
-      $description = [];
-      if ($isolation_level == 'READ-COMMITTED') {
-        if (empty($tables_missing_primary_key)) {
-          $severity_level = RequirementSeverity::OK;
-        }
-        else {
-          $severity_level = RequirementSeverity::Error;
-        }
-      }
-      else {
-        if ($isolation_level == 'REPEATABLE-READ') {
-          $severity_level = RequirementSeverity::Warning;
-        }
-        else {
-          $severity_level = RequirementSeverity::Error;
-          $description[] = $this->t('This is not supported by Drupal.');
-        }
-        $description[] = $this->t('The recommended level for Drupal is "READ COMMITTED".');
-      }
-
-      if (!empty($tables_missing_primary_key)) {
-        $description[] = $this->t('For this to work correctly, all tables must have a primary key. The following table(s) do not have a primary key: @tables.', ['@tables' => implode(', ', $tables_missing_primary_key)]);
-      }
-
-      $description[] = $this->t('See the <a href=":performance_doc">setting MySQL transaction isolation level</a> page for more information.', [
-        ':performance_doc' => 'https://www.drupal.org/docs/system-requirements/setting-the-mysql-transaction-isolation-level',
-      ]);
+    if (!Database::isActiveConnection()) {
+      return [];
+    }
 
-      $requirements['mysql_transaction_level'] = [
-        'title' => $this->t('Transaction isolation level'),
-        'severity' => $severity_level,
-        'value' => $isolation_level,
-        'description' => Markup::create(implode(' ', $description)),
-      ];
+    $connection = Database::getConnection();
+    // Only show requirements when MySQL is the default database connection.
+    if (!($connection->driver() === 'mysql' && $connection->getProvider() === 'mysql')) {
+      return [];
     }
 
-    return $requirements;
+    return $this->getRuntimeRequirements($connection);
   }
 
 }
diff --git a/core/modules/mysql/src/RequirementsTrait.php b/core/modules/mysql/src/RequirementsTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..3aa18b1760445227c376750787d885aceca1fdf4
--- /dev/null
+++ b/core/modules/mysql/src/RequirementsTrait.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\mysql;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
+use Drupal\Core\Render\Markup;
+
+/**
+ * Runtime requirements trait.
+ *
+ * The mysql and the mysqli drivers share the same requirements; this trait
+ * helps sharing them.
+ */
+trait RequirementsTrait {
+
+  /**
+   * Returns runtime requirements.
+   */
+  public function getRuntimeRequirements(Connection $connection): array {
+    $requirements = [];
+
+    // Transaction isolation level.
+    $query = $connection->isMariaDb() ? 'SELECT @@SESSION.tx_isolation' : 'SELECT @@SESSION.transaction_isolation';
+    $isolation_level = $connection->query($query)->fetchField();
+
+    // Tables missing primary key.
+    $tables_missing_primary_key = [];
+    $tables = $connection->schema()->findTables('%');
+    foreach ($tables as $table) {
+      $primary_key_column = $connection->query("SHOW KEYS FROM {" . $table . "} WHERE Key_name = 'PRIMARY'")->fetchAllAssoc('Column_name');
+      if (empty($primary_key_column)) {
+        $tables_missing_primary_key[] = $table;
+      }
+    }
+
+    $description = [];
+    if ($isolation_level == 'READ-COMMITTED') {
+      if (empty($tables_missing_primary_key)) {
+        $severity_level = RequirementSeverity::OK;
+      }
+      else {
+        $severity_level = RequirementSeverity::Error;
+      }
+    }
+    else {
+      if ($isolation_level == 'REPEATABLE-READ') {
+        $severity_level = RequirementSeverity::Warning;
+      }
+      else {
+        $severity_level = RequirementSeverity::Error;
+        $description[] = $this->t('This is not supported by Drupal.');
+      }
+      $description[] = $this->t('The recommended level for Drupal is "READ COMMITTED".');
+    }
+
+    if (!empty($tables_missing_primary_key)) {
+      $description[] = $this->t('For this to work correctly, all tables must have a primary key. The following table(s) do not have a primary key: @tables.', ['@tables' => implode(', ', $tables_missing_primary_key)]);
+    }
+
+    $description[] = $this->t('See the <a href=":performance_doc">setting MySQL transaction isolation level</a> page for more information.', [
+      ':performance_doc' => 'https://www.drupal.org/docs/system-requirements/setting-the-mysql-transaction-isolation-level',
+    ]);
+
+    $requirements['mysql_transaction_level'] = [
+      'title' => $this->t('Transaction isolation level'),
+      'severity' => $severity_level,
+      'value' => $isolation_level,
+      'description' => Markup::create(implode(' ', $description)),
+    ];
+
+    return $requirements;
+  }
+
+}
diff --git a/core/modules/mysqli/src/Hook/MysqliHooks.php b/core/modules/mysqli/src/Hook/MysqliHooks.php
index 340b17373a1214c8b487dd7d66a8b474481e3f43..556ea12846c4a6bfc483b7e4c07bd8ea222d5c0b 100644
--- a/core/modules/mysqli/src/Hook/MysqliHooks.php
+++ b/core/modules/mysqli/src/Hook/MysqliHooks.php
@@ -3,17 +3,17 @@
 namespace Drupal\mysqli\Hook;
 
 use Drupal\Core\Database\Database;
-use Drupal\Core\Extension\Requirement\RequirementSeverity;
 use Drupal\Core\Hook\Attribute\Hook;
-use Drupal\Core\Render\Markup;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\mysql\RequirementsTrait;
 
 /**
  * Hook implementations for mysqli.
  */
 class MysqliHooks {
 
+  use RequirementsTrait;
   use StringTranslationTrait;
 
   /**
@@ -37,66 +37,17 @@ public function help($route_name, RouteMatchInterface $route_match): ?string {
    */
   #[Hook('runtime_requirements')]
   public function runtimeRequirements(): array {
-    $requirements = [];
-
-    // Test with MySql databases.
-    if (Database::isActiveConnection()) {
-      $connection = Database::getConnection();
-      // Only show requirements when MySQLi is the default database connection.
-      if (!($connection->driver() === 'mysqli' && $connection->getProvider() === 'mysqli')) {
-        return [];
-      }
-
-      $query = $connection->isMariaDb() ? 'SELECT @@SESSION.tx_isolation' : 'SELECT @@SESSION.transaction_isolation';
-
-      $isolation_level = $connection->query($query)->fetchField();
-
-      $tables_missing_primary_key = [];
-      $tables = $connection->schema()->findTables('%');
-      foreach ($tables as $table) {
-        $primary_key_column = Database::getConnection()->query("SHOW KEYS FROM {" . $table . "} WHERE Key_name = 'PRIMARY'")->fetchAllAssoc('Column_name');
-        if (empty($primary_key_column)) {
-          $tables_missing_primary_key[] = $table;
-        }
-      }
-
-      $description = [];
-      if ($isolation_level == 'READ-COMMITTED') {
-        if (empty($tables_missing_primary_key)) {
-          $severity_level = RequirementSeverity::OK;
-        }
-        else {
-          $severity_level = RequirementSeverity::Error;
-        }
-      }
-      else {
-        if ($isolation_level == 'REPEATABLE-READ') {
-          $severity_level = RequirementSeverity::Warning;
-        }
-        else {
-          $severity_level = RequirementSeverity::Error;
-          $description[] = $this->t('This is not supported by Drupal.');
-        }
-        $description[] = $this->t('The recommended level for Drupal is "READ COMMITTED".');
-      }
-
-      if (!empty($tables_missing_primary_key)) {
-        $description[] = $this->t('For this to work correctly, all tables must have a primary key. The following table(s) do not have a primary key: @tables.', ['@tables' => implode(', ', $tables_missing_primary_key)]);
-      }
-
-      $description[] = $this->t('See the <a href=":performance_doc">setting MySQL transaction isolation level</a> page for more information.', [
-        ':performance_doc' => 'https://www.drupal.org/docs/system-requirements/setting-the-mysql-transaction-isolation-level',
-      ]);
+    if (!Database::isActiveConnection()) {
+      return [];
+    }
 
-      $requirements['mysql_transaction_level'] = [
-        'title' => $this->t('Transaction isolation level'),
-        'severity' => $severity_level,
-        'value' => $isolation_level,
-        'description' => Markup::create(implode(' ', $description)),
-      ];
+    $connection = Database::getConnection();
+    // Only show requirements when MySQLi is the default database connection.
+    if (!($connection->driver() === 'mysqli' && $connection->getProvider() === 'mysqli')) {
+      return [];
     }
 
-    return $requirements;
+    return $this->getRuntimeRequirements($connection);
   }
 
 }