diff --git a/vendor/magento/module-quote/Model/CartLockedException.php b/vendor/magento/module-quote/Model/CartLockedException.php
new file mode 100644
index 00000000000..7f2aa877842
--- /dev/null
+++ b/vendor/magento/module-quote/Model/CartLockedException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Quote\Model;
+
+use Magento\Framework\Exception\StateException;
+
+/**
+ * Thrown when the cart is locked for processing.
+ */
+class CartLockedException extends StateException
+{
+
+}
diff --git a/vendor/magento/module-quote/Model/CartMutex.php b/vendor/magento/module-quote/Model/CartMutex.php
new file mode 100644
index 00000000000..398c180c71e
--- /dev/null
+++ b/vendor/magento/module-quote/Model/CartMutex.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Quote\Model;
+
+use Magento\Framework\Lock\LockManagerInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @inheritDoc
+ */
+class CartMutex implements CartMutexInterface
+{
+    /**
+     * @var LockManagerInterface
+     */
+    private $lockManager;
+
+    /**
+     * @var LoggerInterface
+     */
+    private $logger;
+
+    /**
+     * @param LockManagerInterface $lockManager
+     * @param LoggerInterface $logger
+     */
+    public function __construct(
+        LockManagerInterface $lockManager,
+        LoggerInterface $logger
+    ) {
+        $this->lockManager = $lockManager;
+        $this->logger = $logger;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function execute(int $id, callable $callable, array $args = [])
+    {
+        $lockName = 'cart_lock_' . $id;
+
+        if (!$this->lockManager->lock($lockName, 0)) {
+            $this->logger->critical(
+                'The cart is locked for processing, the request has been aborted. Quote ID: ' . $id
+            );
+            throw new CartLockedException(
+                __('The cart is locked for processing. Please try again later.')
+            );
+        }
+
+        try {
+            $result = $callable(...$args);
+        } finally {
+            $this->lockManager->unlock($lockName);
+        }
+
+        return $result;
+    }
+}
diff --git a/vendor/magento/module-quote/Model/CartMutexInterface.php b/vendor/magento/module-quote/Model/CartMutexInterface.php
new file mode 100644
index 00000000000..6681c638829
--- /dev/null
+++ b/vendor/magento/module-quote/Model/CartMutexInterface.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Quote\Model;
+
+/**
+ * Intended to prevent race conditions during quote processing by concurrent requests.
+ */
+interface CartMutexInterface
+{
+    /**
+     * Acquires a lock for quote, executes callable and releases the lock after.
+     *
+     * @param int $id
+     * @param callable $callable
+     * @param array $args
+     * @return mixed
+     * @throws CartLockedException
+     */
+    public function execute(int $id, callable $callable, array $args = []);
+}
diff --git a/vendor/magento/module-quote/Model/QuoteManagement.php b/vendor/magento/module-quote/Model/QuoteManagement.php
index 51b68411d40..73476caaba5 100644
--- a/vendor/magento/module-quote/Model/QuoteManagement.php
+++ b/vendor/magento/module-quote/Model/QuoteManagement.php
@@ -176,6 +176,11 @@ class QuoteManagement implements CartManagementInterface
      */
     private $remoteAddress;
 
+    /**
+     * @var CartMutexInterface
+     */
+    private $cartMutex;
+
     /**
      * @param EventManager $eventManager
      * @param SubmitQuoteValidator $submitQuoteValidator
@@ -200,8 +205,9 @@ class QuoteManagement implements CartManagementInterface
      * @param QuoteIdMaskFactory|null $quoteIdMaskFactory
      * @param AddressRepositoryInterface|null $addressRepository
      * @param RequestInterface|null $request
-     * @param RemoteAddress $remoteAddress
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     * @param RemoteAddress|null $remoteAddress
+     * @param CartMutexInterface|null $cartMutex
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(
         EventManager $eventManager,
@@ -227,7 +233,8 @@ class QuoteManagement implements CartManagementInterface
         QuoteIdMaskFactory $quoteIdMaskFactory = null,
         AddressRepositoryInterface $addressRepository = null,
         RequestInterface $request = null,
-        RemoteAddress $remoteAddress = null
+        RemoteAddress $remoteAddress = null,
+        ?CartMutexInterface $cartMutex = null
     ) {
         $this->eventManager = $eventManager;
         $this->submitQuoteValidator = $submitQuoteValidator;
@@ -257,6 +264,8 @@ class QuoteManagement implements CartManagementInterface
             ->get(RequestInterface::class);
         $this->remoteAddress = $remoteAddress ?: ObjectManager::getInstance()
             ->get(RemoteAddress::class);
+        $this->cartMutex = $cartMutex
+            ?? ObjectManager::getInstance()->get(CartMutexInterface::class);
     }
 
     /**
@@ -382,10 +391,28 @@ class QuoteManagement implements CartManagementInterface
 
     /**
      * @inheritdoc
+     */
+    public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
+    {
+        return $this->cartMutex->execute(
+            (int)$cartId,
+            \Closure::fromCallable([$this, 'placeOrderRun']),
+            [$cartId, $paymentMethod]
+        );
+    }
+
+    /**
+     * Places an order for a specified cart.
+     *
+     * @param int $cartId The cart ID.
+     * @param PaymentInterface|null $paymentMethod
+     * @throws CouldNotSaveException
+     * @return int Order ID.
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
      */
-    public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
+    private function placeOrderRun($cartId, PaymentInterface $paymentMethod = null)
     {
         $quote = $this->quoteRepository->getActive($cartId);
         $customer = $quote->getCustomer();
diff --git a/vendor/magento/module-quote/Model/QuoteRepository.php b/vendor/magento/module-quote/Model/QuoteRepository.php
index b1bef834197..483b3724044 100644
--- a/vendor/magento/module-quote/Model/QuoteRepository.php
+++ b/vendor/magento/module-quote/Model/QuoteRepository.php
@@ -165,6 +165,7 @@ class QuoteRepository implements CartRepositoryInterface
      */
     public function getActive($cartId, array $sharedStoreIds = [])
     {
+        $this->validateCachedActiveQuote((int)$cartId);
         $quote = $this->get($cartId, $sharedStoreIds);
         if (!$quote->getIsActive()) {
             throw NoSuchEntityException::singleField('cartId', $cartId);
@@ -172,11 +173,33 @@ class QuoteRepository implements CartRepositoryInterface
         return $quote;
     }
 
+    /**
+     * Validates if cached quote is still active.
+     *
+     * @param int $cartId
+     * @return void
+     * @throws NoSuchEntityException
+     */
+    private function validateCachedActiveQuote(int $cartId): void
+    {
+        if (isset($this->quotesById[$cartId])) {
+            $quote = $this->cartFactory->create();
+            if (is_callable([$quote, 'setSharedStoreIds'])) {
+                $quote->setSharedStoreIds(['*']);
+            }
+            $quote->loadActive($cartId);
+            if (!$quote->getIsActive()) {
+                throw NoSuchEntityException::singleField('cartId', $cartId);
+            }
+        }
+    }
+
     /**
      * @inheritdoc
      */
     public function getActiveForCustomer($customerId, array $sharedStoreIds = [])
     {
+        $this->validateCachedCustomerActiveQuote((int)$customerId);
         $quote = $this->getForCustomer($customerId, $sharedStoreIds);
         if (!$quote->getIsActive()) {
             throw NoSuchEntityException::singleField('customerId', $customerId);
@@ -184,6 +207,28 @@ class QuoteRepository implements CartRepositoryInterface
         return $quote;
     }
 
+    /**
+     * Validates if cached customer quote is still active.
+     *
+     * @param int $customerId
+     * @return void
+     * @throws NoSuchEntityException
+     */
+    private function validateCachedCustomerActiveQuote(int $customerId): void
+    {
+        if (isset($this->quotesByCustomerId[$customerId])) {
+            $quoteId = $this->quotesByCustomerId[$customerId]->getId();
+            $quote = $this->cartFactory->create();
+            if (is_callable([$quote, 'setSharedStoreIds'])) {
+                $quote->setSharedStoreIds(['*']);
+            }
+            $quote->loadActive($quoteId);
+            if (!$quote->getIsActive()) {
+                throw NoSuchEntityException::singleField('customerId', $customerId);
+            }
+        }
+    }
+
     /**
      * @inheritdoc
      */
diff --git a/vendor/magento/module-quote/etc/di.xml b/vendor/magento/module-quote/etc/di.xml
index 01821c63801..5e945d583d5 100644
--- a/vendor/magento/module-quote/etc/di.xml
+++ b/vendor/magento/module-quote/etc/di.xml
@@ -45,6 +45,7 @@
     <preference for="Magento\Quote\Api\Data\ProductOptionInterface" type="Magento\Quote\Model\Quote\ProductOption" />
     <preference for="Magento\Quote\Model\ValidationRules\QuoteValidationRuleInterface" type="Magento\Quote\Model\ValidationRules\QuoteValidationComposite\Proxy"/>
     <preference for="Magento\Quote\Model\QuoteMutexInterface" type="Magento\Quote\Model\QuoteMutex"/>
+    <preference for="Magento\Quote\Model\CartMutexInterface" type="Magento\Quote\Model\CartMutex"/>
     <preference for="Magento\Quote\Model\Quote\Item\Option\ComparatorInterface" type="Magento\Quote\Model\Quote\Item\Option\Comparator"/>
     <type name="Magento\Webapi\Controller\Rest\ParamsOverrider">
         <arguments>
diff --git a/vendor/magento/module-quote/i18n/en_US.csv b/vendor/magento/module-quote/i18n/en_US.csv
index c899c432c70..4240990fd87 100644
--- a/vendor/magento/module-quote/i18n/en_US.csv
+++ b/vendor/magento/module-quote/i18n/en_US.csv
@@ -68,3 +68,4 @@ Carts,Carts
 "Invalid state change requested","Invalid state change requested"
 "Validated Country Code","Validated Country Code"
 "Validated Vat Number","Validated Vat Number"
+"The cart is locked for processing. Please try again later.","The cart is locked for processing. Please try again later."
