Skip to content

Commit 7c63371

Browse files
ACPT-757: Fix Deadlock in Magento\UrlRewrite\Model\Storage\DbStorage
2: No longer deleting rows that we are just going to insert back in. Using upsert instead of insert. (unique key is (`request_path`,`store_id`))
1 parent 6a59f3e commit 7c63371

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

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

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -222,30 +222,26 @@ private function deleteOldUrls(array $urls): void
222222
$oldUrlsSelect->from(
223223
$this->resource->getTableName(self::TABLE_NAME)
224224
);
225-
226225
$uniqueEntities = $this->prepareUniqueEntities($urls);
227226
foreach ($uniqueEntities as $storeId => $entityTypes) {
228227
foreach ($entityTypes as $entityType => $entities) {
229228
$oldUrlsSelect->orWhere(
230-
$this->connection->quoteIdentifier(
231-
UrlRewrite::STORE_ID
232-
) . ' = ' . $this->connection->quote($storeId, 'INTEGER') .
233-
' AND ' . $this->connection->quoteIdentifier(
234-
UrlRewrite::ENTITY_ID
235-
) . ' IN (' . $this->connection->quote($entities, 'INTEGER') . ')' .
236-
' AND ' . $this->connection->quoteIdentifier(
237-
UrlRewrite::ENTITY_TYPE
238-
) . ' = ' . $this->connection->quote($entityType)
229+
$this->connection->quoteIdentifier(UrlRewrite::STORE_ID)
230+
. ' = ' . $this->connection->quote($storeId, 'INTEGER') .
231+
' AND ' . $this->connection->quoteIdentifier(UrlRewrite::ENTITY_ID)
232+
. ' IN (' . $this->connection->quote(array_keys($entities), 'INTEGER') . ')' .
233+
' AND ' . $this->connection->quoteIdentifier(UrlRewrite::ENTITY_TYPE)
234+
. ' = ' . $this->connection->quote($entityType) .
235+
' AND ' . $this->connection->quoteIdentifier(UrlRewrite::REQUEST_PATH)
236+
. ' NOT IN (' . $this->connection->quote(array_merge(...$entities)) . ')'
239237
);
240238
}
241239
}
242-
243240
// prevent query locking in a case when nothing to delete
244241
$checkOldUrlsSelect = clone $oldUrlsSelect;
245242
$checkOldUrlsSelect->reset(Select::COLUMNS);
246243
$checkOldUrlsSelect->columns('count(*)');
247244
$hasOldUrls = (bool)$this->connection->fetchOne($checkOldUrlsSelect);
248-
249245
if ($hasOldUrls) {
250246
$this->connection->query(
251247
$oldUrlsSelect->deleteFromSelect(
@@ -264,17 +260,9 @@ private function deleteOldUrls(array $urls): void
264260
private function prepareUniqueEntities(array $urls): array
265261
{
266262
$uniqueEntities = [];
267-
/** @var UrlRewrite $url */
268263
foreach ($urls as $url) {
269-
$entityIds = (!empty($uniqueEntities[$url->getStoreId()][$url->getEntityType()])) ?
270-
$uniqueEntities[$url->getStoreId()][$url->getEntityType()] : [];
271-
272-
if (!\in_array($url->getEntityId(), $entityIds)) {
273-
$entityIds[] = $url->getEntityId();
274-
}
275-
$uniqueEntities[$url->getStoreId()][$url->getEntityType()] = $entityIds;
264+
$uniqueEntities[$url->getStoreId()][$url->getEntityType()][$url->getEntityId()][] = $url->getRequestPath();
276265
}
277-
278266
return $uniqueEntities;
279267
}
280268

@@ -291,7 +279,7 @@ protected function doReplace(array $urls): array
291279
foreach ($urls as $url) {
292280
$data[] = $url->toArray();
293281
}
294-
$this->insertMultiple($data);
282+
$this->upsertMultiple($data);
295283
$this->connection->commit();
296284
} catch (\Magento\Framework\DB\Adapter\DeadlockException $deadlockException) {
297285
continue;
@@ -336,6 +324,8 @@ protected function doReplace(array $urls): array
336324
* @return void
337325
* @throws \Magento\Framework\Exception\AlreadyExistsException|\Exception
338326
* @throws \Exception
327+
* @deprecated Not used anymore.
328+
* @see upsertMultiple
339329
*/
340330
protected function insertMultiple($data): void
341331
{
@@ -354,6 +344,17 @@ protected function insertMultiple($data): void
354344
}
355345
}
356346

347+
/**
348+
* Upsert multiple
349+
*
350+
* @param array $data
351+
* @return void
352+
*/
353+
private function upsertMultiple(array $data): void
354+
{
355+
$this->connection->insertOnDuplicate($this->resource->getTableName(self::TABLE_NAME), $data);
356+
}
357+
357358
/**
358359
* Get filter for url rows deletion due to provided urls
359360
*

0 commit comments

Comments
 (0)