Skip to content

Commit 6a59f3e

Browse files
ACPT-757: Fix Deadlock in Magento\UrlRewrite\Model\Storage\DbStorage
1: Catching DeadlockException and retrying (up to 3 tries)
1 parent e0d650c commit 6a59f3e

File tree

1 file changed

+50
-45
lines changed

1 file changed

+50
-45
lines changed

app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,31 @@ class DbStorage extends AbstractStorage
4848
*/
4949
private $logger;
5050

51+
52+
/**
53+
* @var int
54+
*/
55+
private $maxRetryCount;
56+
5157
/**
5258
* @param UrlRewriteFactory $urlRewriteFactory
5359
* @param DataObjectHelper $dataObjectHelper
5460
* @param ResourceConnection $resource
5561
* @param LoggerInterface|null $logger
62+
* @param int $maxRetryCount
5663
*/
5764
public function __construct(
5865
UrlRewriteFactory $urlRewriteFactory,
5966
DataObjectHelper $dataObjectHelper,
6067
ResourceConnection $resource,
61-
LoggerInterface $logger = null
68+
LoggerInterface $logger = null,
69+
int $maxRetryCount = 3
6270
) {
6371
$this->connection = $resource->getConnection();
6472
$this->resource = $resource;
6573
$this->logger = $logger ?: ObjectManager::getInstance()
6674
->get(LoggerInterface::class);
67-
75+
$this->maxRetryCount = $maxRetryCount;
6876
parent::__construct($urlRewriteFactory, $dataObjectHelper);
6977
}
7078

@@ -275,52 +283,49 @@ private function prepareUniqueEntities(array $urls): array
275283
*/
276284
protected function doReplace(array $urls): array
277285
{
278-
$this->connection->beginTransaction();
279-
280-
try {
281-
$this->deleteOldUrls($urls);
282-
283-
$data = [];
284-
foreach ($urls as $url) {
285-
$data[] = $url->toArray();
286-
}
287-
288-
$this->insertMultiple($data);
289-
290-
$this->connection->commit();
291-
// @codingStandardsIgnoreStart
292-
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
293-
// @codingStandardsIgnoreEnd
294-
$this->connection->rollBack();
295-
296-
/** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urlConflicted */
297-
$urlConflicted = [];
298-
foreach ($urls as $url) {
299-
$urlFound = $this->doFindOneByData(
300-
[
301-
UrlRewrite::REQUEST_PATH => $url->getRequestPath(),
302-
UrlRewrite::STORE_ID => $url->getStoreId(),
303-
]
304-
);
305-
if (isset($urlFound[UrlRewrite::URL_REWRITE_ID])) {
306-
$urlConflicted[$urlFound[UrlRewrite::URL_REWRITE_ID]] = $url->toArray();
286+
for ($tries = 0; $tries < $this->maxRetryCount; $tries++) {
287+
$this->connection->beginTransaction();
288+
try {
289+
$this->deleteOldUrls($urls);
290+
$data = [];
291+
foreach ($urls as $url) {
292+
$data[] = $url->toArray();
307293
}
294+
$this->insertMultiple($data);
295+
$this->connection->commit();
296+
} catch (\Magento\Framework\DB\Adapter\DeadlockException $deadlockException) {
297+
continue;
298+
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
299+
$this->connection->rollBack();
300+
/** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urlConflicted */
301+
$urlConflicted = [];
302+
foreach ($urls as $url) {
303+
$urlFound = $this->doFindOneByData(
304+
[
305+
UrlRewrite::REQUEST_PATH => $url->getRequestPath(),
306+
UrlRewrite::STORE_ID => $url->getStoreId(),
307+
]
308+
);
309+
if (isset($urlFound[UrlRewrite::URL_REWRITE_ID])) {
310+
$urlConflicted[$urlFound[UrlRewrite::URL_REWRITE_ID]] = $url->toArray();
311+
}
312+
}
313+
if ($urlConflicted) {
314+
throw new \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException(
315+
__('URL key for specified store already exists.'),
316+
$e,
317+
$e->getCode(),
318+
$urlConflicted
319+
);
320+
} else {
321+
throw $e->getPrevious() ?: $e;
322+
}
323+
} catch (\Exception $e) {
324+
$this->connection->rollBack();
325+
throw $e;
308326
}
309-
if ($urlConflicted) {
310-
throw new \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException(
311-
__('URL key for specified store already exists.'),
312-
$e,
313-
$e->getCode(),
314-
$urlConflicted
315-
);
316-
} else {
317-
throw $e->getPrevious() ?: $e;
318-
}
319-
} catch (\Exception $e) {
320-
$this->connection->rollBack();
321-
throw $e;
327+
break;
322328
}
323-
324329
return $urls;
325330
}
326331

0 commit comments

Comments
 (0)