diff --git a/config/database.php b/config/database.php index 8a3b731fb52e..b8e0e160bdcf 100644 --- a/config/database.php +++ b/config/database.php @@ -41,6 +41,7 @@ 'busy_timeout' => null, 'journal_mode' => null, 'synchronous' => null, + 'transaction_mode' => 'DEFERRED', ], 'mysql' => [ diff --git a/src/Illuminate/Database/Concerns/ManagesTransactions.php b/src/Illuminate/Database/Concerns/ManagesTransactions.php index 23bc60434e49..afb1513fb400 100644 --- a/src/Illuminate/Database/Concerns/ManagesTransactions.php +++ b/src/Illuminate/Database/Concerns/ManagesTransactions.php @@ -3,10 +3,14 @@ namespace Illuminate\Database\Concerns; use Closure; +use Illuminate\Database\Connection; use Illuminate\Database\DeadlockException; use RuntimeException; use Throwable; +/** + * @mixin Connection + */ trait ManagesTransactions { /** @@ -148,7 +152,7 @@ protected function createTransaction() $this->reconnectIfMissingConnection(); try { - $this->getPdo()->beginTransaction(); + $this->executeBeginTransactionStatement(); } catch (Throwable $e) { $this->handleBeginTransactionException($e); } @@ -184,7 +188,7 @@ protected function handleBeginTransactionException(Throwable $e) if ($this->causedByLostConnection($e)) { $this->reconnect(); - $this->getPdo()->beginTransaction(); + $this->executeBeginTransactionStatement(); } else { throw $e; } diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index 9910fe911b66..c00987db53ae 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -1470,6 +1470,16 @@ public function unsetEventDispatcher() $this->events = null; } + /** + * Run the statement to start a new transaction. + * + * @return void + */ + protected function executeBeginTransactionStatement() + { + $this->getPdo()->beginTransaction(); + } + /** * Set the transaction manager instance on the connection. * diff --git a/src/Illuminate/Database/SQLiteConnection.php b/src/Illuminate/Database/SQLiteConnection.php index 53cbfad42c9d..42a5947741f2 100755 --- a/src/Illuminate/Database/SQLiteConnection.php +++ b/src/Illuminate/Database/SQLiteConnection.php @@ -20,6 +20,24 @@ public function getDriverTitle() return 'SQLite'; } + /** + * Run the statement to start a new transaction. + * + * @return void + */ + protected function executeBeginTransactionStatement() + { + if (version_compare(PHP_VERSION, '8.4.0') >= 0) { + $mode = $this->getConfig('transaction_mode') ?? 'DEFERRED'; + + $this->getPdo()->exec("BEGIN {$mode} TRANSACTION"); + + return; + } + + $this->getPdo()->beginTransaction(); + } + /** * Escape a binary value for safe SQL embedding. *