diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php index ef6027256c..3436ec7366 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php @@ -220,10 +220,13 @@ public static function open(array &$connection_options = []) { // by one. $connection_options += [ 'init_commands' => [], + // @todo Switch to 'READ COMMITTED' for Drupal 10, see https://www.drupal.org/node/1650930 + 'isolation_level' => 'REPEATABLE READ', ]; $connection_options['init_commands'] += [ 'sql_mode' => "SET sql_mode = 'ANSI,TRADITIONAL'", + 'isolation' => 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $connection_options['isolation_level'], ]; // Execute initial commands. diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php index dfac0158b7..2b5bf9f617 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php @@ -175,6 +175,12 @@ public function getFormOptions(array $database) { $form['advanced_options']['port']['#default_value'] = '3306'; } + // Add the isolation_level option to settings.php. + $form['isolation_level'] = [ + '#type' => 'value', + '#default_value' => empty($database['isolation_level']) ? 'READ COMMITTED' : $database['isolation_level'], + ]; + return $form; } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php index 9da21be807..d7d1f678fa 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php @@ -301,6 +301,8 @@ protected function getCredentials() { $drivers = drupal_get_database_types(); $form = $drivers[$driver]->getFormOptions($connection_options); $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); + // Remove isolation_level since that options is not configurable in the UI. + unset($connection_options['isolation_level']); $edit = [ $driver => $connection_options, 'source_private_file_path' => $this->getSourceBasePath(), diff --git a/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelExistingDatabaseSettingsTest.php b/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelExistingDatabaseSettingsTest.php new file mode 100644 index 0000000000..cb46cb8cf8 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelExistingDatabaseSettingsTest.php @@ -0,0 +1,49 @@ +markTestSkipped("This test does not support the {$connection_info['default']['driver']} database driver."); + } + + // Pre-configure database credentials in settings.php. + unset($connection_info['default']['pdo'], $connection_info['default']['init_commands']); + $connection_info['default']['isolation_level'] = 'REPEATABLE READ'; + + $this->settings['databases']['default'] = (object) [ + 'value' => $connection_info, + 'required' => TRUE, + ]; + } + + /** + * Verifies that isolation_level is not overridden in the database settings. + */ + public function testInstaller() { + $contents = file_get_contents($this->container->getParameter('app.root') . '/' . $this->siteDirectory . '/settings.php'); + $this->assertStringContainsString("'isolation_level' => 'REPEATABLE READ',", $contents); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelNoDatabaseSettingsTest.php b/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelNoDatabaseSettingsTest.php new file mode 100644 index 0000000000..5e66cd0a59 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Installer/InstallerIsolationLevelNoDatabaseSettingsTest.php @@ -0,0 +1,40 @@ +markTestSkipped("This test does not support the {$connection_info['default']['driver']} database driver."); + } + } + + /** + * Verifies that the isolation_level was added to the database settings. + */ + public function testInstaller() { + $contents = file_get_contents($this->container->getParameter('app.root') . '/' . $this->siteDirectory . '/settings.php'); + $this->assertStringContainsString("'isolation_level' => 'READ COMMITTED',", $contents); + } + +}