|
16 | 16 | use Doctrine\DBAL\Exception as DBALException;
|
17 | 17 | use Doctrine\DBAL\Exception\TableNotFoundException;
|
18 | 18 | use Doctrine\DBAL\LockMode;
|
19 |
| -use Doctrine\DBAL\Platforms\MariaDb1060Platform; |
20 |
| -use Doctrine\DBAL\Platforms\MariaDBPlatform; |
21 |
| -use Doctrine\DBAL\Platforms\MySQL57Platform; |
22 |
| -use Doctrine\DBAL\Platforms\MySQL80Platform; |
23 | 19 | use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
|
24 |
| -use Doctrine\DBAL\Platforms\MySQLPlatform; |
25 | 20 | use Doctrine\DBAL\Platforms\OraclePlatform;
|
26 |
| -use Doctrine\DBAL\Platforms\PostgreSQL100Platform; |
27 |
| -use Doctrine\DBAL\Platforms\PostgreSQLPlatform; |
28 |
| -use Doctrine\DBAL\Platforms\SQLServerPlatform; |
29 | 21 | use Doctrine\DBAL\Query\ForUpdate\ConflictResolutionMode;
|
30 | 22 | use Doctrine\DBAL\Query\QueryBuilder;
|
31 | 23 | use Doctrine\DBAL\Result;
|
@@ -189,28 +181,22 @@ public function get(): ?array
|
189 | 181 | ->where('w.id IN ('.str_replace('SELECT a.* FROM', 'SELECT a.id FROM', $sql).')')
|
190 | 182 | ->setParameters($query->getParameters());
|
191 | 183 |
|
192 |
| - if (method_exists(QueryBuilder::class, 'forUpdate')) { |
193 |
| - $query->forUpdate(); |
194 |
| - } |
195 |
| - |
196 | 184 | $sql = $query->getSQL();
|
197 |
| - } elseif (method_exists(QueryBuilder::class, 'forUpdate')) { |
198 |
| - $query->forUpdate(ConflictResolutionMode::SKIP_LOCKED); |
199 |
| - try { |
200 |
| - $sql = $query->getSQL(); |
201 |
| - } catch (DBALException $e) { |
202 |
| - } |
203 |
| - } elseif (preg_match('/FROM (.+) WHERE/', (string) $sql, $matches)) { |
204 |
| - $fromClause = $matches[1]; |
205 |
| - $sql = str_replace( |
206 |
| - sprintf('FROM %s WHERE', $fromClause), |
207 |
| - sprintf('FROM %s WHERE', $this->driverConnection->getDatabasePlatform()->appendLockHint($fromClause, LockMode::PESSIMISTIC_WRITE)), |
208 |
| - $sql |
209 |
| - ); |
210 | 185 | }
|
211 | 186 |
|
212 |
| - // use SELECT ... FOR UPDATE to lock table |
213 |
| - if (!method_exists(QueryBuilder::class, 'forUpdate') || $this->isDbal38OrHigherAndOldPlatform()) { |
| 187 | + if (method_exists(QueryBuilder::class, 'forUpdate')) { |
| 188 | + $sql = $this->addLockMode($query, $sql); |
| 189 | + } else { |
| 190 | + if (preg_match('/FROM (.+) WHERE/', (string) $sql, $matches)) { |
| 191 | + $fromClause = $matches[1]; |
| 192 | + $sql = str_replace( |
| 193 | + sprintf('FROM %s WHERE', $fromClause), |
| 194 | + sprintf('FROM %s WHERE', $this->driverConnection->getDatabasePlatform()->appendLockHint($fromClause, LockMode::PESSIMISTIC_WRITE)), |
| 195 | + $sql |
| 196 | + ); |
| 197 | + } |
| 198 | + |
| 199 | + // use SELECT ... FOR UPDATE to lock table |
214 | 200 | $sql .= ' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL();
|
215 | 201 | }
|
216 | 202 |
|
@@ -505,17 +491,23 @@ private function updateSchema(): void
|
505 | 491 | }
|
506 | 492 | }
|
507 | 493 |
|
508 |
| - /** |
509 |
| - * @throws DBALException |
510 |
| - */ |
511 |
| - public function isDbal38OrHigherAndOldPlatform(): bool |
| 494 | + private function addLockMode(QueryBuilder $query, string $sql): string |
512 | 495 | {
|
513 |
| - $platform = $this->driverConnection->getDatabasePlatform(); |
| 496 | + $query->forUpdate(ConflictResolutionMode::SKIP_LOCKED); |
| 497 | + try { |
| 498 | + return $query->getSQL(); |
| 499 | + } catch (DBALException) { |
| 500 | + return $this->fallBackToForUpdate($query, $sql); |
| 501 | + } |
| 502 | + } |
514 | 503 |
|
515 |
| - return method_exists(QueryBuilder::class, 'forUpdate') |
516 |
| - && method_exists($platform::class, 'getWriteLockSQL') |
517 |
| - && (($platform instanceof MySQLPlatform && !$platform instanceof MySQL80Platform && !$platform instanceof MariaDBPlatform) |
518 |
| - || ($platform instanceof MariaDBPlatform && !$platform instanceof MariaDb1060Platform) |
519 |
| - || ($platform instanceof PostgreSQLPlatform && !$platform instanceof PostgreSQL100Platform)); |
| 504 | + private function fallBackToForUpdate(QueryBuilder $query, string $sql): string |
| 505 | + { |
| 506 | + $query->forUpdate(); |
| 507 | + try { |
| 508 | + return $query->getSQL(); |
| 509 | + } catch (DBALException) { |
| 510 | + return $sql; |
| 511 | + } |
520 | 512 | }
|
521 | 513 | }
|
0 commit comments