[Messenger] Fix mssql compatibility for doctrine transport.

Add logic for locking row for update when the doctrine dbal connection is sqlsrv. This is a quick and dirty solution, but it prevents the need to rewrite the logic due to doctrine dbal limitations.

See issue https://github.com/symfony/symfony/issues/39117
This commit is contained in:
bill moll 2020-11-24 14:13:56 -06:00 committed by Alexander M. Turek
parent 3e9f770e25
commit 37be094992
1 changed files with 16 additions and 1 deletions

View File

@ -16,6 +16,7 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Result as DriverResult;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\TableNotFoundException;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\Comparator;
@ -161,9 +162,23 @@ class Connection
->orderBy('available_at', 'ASC')
->setMaxResults(1);
// Append pessimistic write lock to FROM clause if db platform supports it
$sql = $query->getSQL();
if (($fromPart = $query->getQueryPart('from')) &&
($table = $fromPart[0]['table'] ?? null) &&
($alias = $fromPart[0]['alias'] ?? null)
) {
$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)),
$sql
);
}
// use SELECT ... FOR UPDATE to lock table
$stmt = $this->executeQuery(
$query->getSQL().' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(),
$sql.' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(),
$query->getParameters(),
$query->getParameterTypes()
);