From 88157c1de8cdf17eb33d81e5241bb68364dd91ee Mon Sep 17 00:00:00 2001 From: Ferror Date: Tue, 18 Jul 2023 15:44:18 +0200 Subject: [PATCH] [messenger] support mysql 8.0 skip locked --- .../Bridge/Doctrine/Transport/Connection.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php index 85f95e088ffe5..b9aac035553ce 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php @@ -18,6 +18,7 @@ use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Platforms\MySQL80Platform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Query\QueryBuilder; @@ -168,11 +169,12 @@ public function get(): ?array get: $this->driverConnection->beginTransaction(); try { + $databasePlatform = $this->driverConnection->getDatabasePlatform(); $query = $this->createAvailableMessagesQueryBuilder() ->orderBy('available_at', 'ASC') ->setMaxResults(1); - if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) { + if ($databasePlatform instanceof OraclePlatform) { $query->select('m.id'); } @@ -185,21 +187,27 @@ public function get(): ?array $fromClause = sprintf('%s %s', $table, $alias); $sql = str_replace( sprintf('FROM %s WHERE', $fromClause), - sprintf('FROM %s WHERE', $this->driverConnection->getDatabasePlatform()->appendLockHint($fromClause, LockMode::PESSIMISTIC_WRITE)), + sprintf('FROM %s WHERE', $databasePlatform->appendLockHint($fromClause, LockMode::PESSIMISTIC_WRITE)), $sql ); } // Wrap the rownum query in a sub-query to allow writelocks without ORA-02014 error - if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) { + if ($databasePlatform instanceof OraclePlatform) { $sql = $this->createQueryBuilder('w') ->where('w.id IN ('.str_replace('SELECT a.* FROM', 'SELECT a.id FROM', $sql).')') ->getSQL(); } // use SELECT ... FOR UPDATE to lock table + $sql .= ' '.$databasePlatform->getWriteLockSQL(); + + if ($databasePlatform instanceof MySQL80Platform) { + $sql .= ' SKIP LOCKED'; + } + $stmt = $this->executeQuery( - $sql.' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(), + $sql, $query->getParameters(), $query->getParameterTypes() );