5353 */
5454class QuoteManagement implements CartManagementInterface, ResetAfterRequestInterface
5555{
56- private const LOCK_PREFIX = 'PLACE_ORDER_ ' ;
57-
58- private const LOCK_TIMEOUT = 0 ;
59-
6056 /**
6157 * @var EventManager
6258 */
@@ -157,11 +153,6 @@ class QuoteManagement implements CartManagementInterface, ResetAfterRequestInter
157153 */
158154 protected $ quoteFactory ;
159155
160- /**
161- * @var LockManagerInterface
162- */
163- private $ lockManager ;
164-
165156 /**
166157 * @var QuoteIdMaskFactory
167158 */
@@ -187,6 +178,11 @@ class QuoteManagement implements CartManagementInterface, ResetAfterRequestInter
187178 */
188179 private $ remoteAddress ;
189180
181+ /**
182+ * @var CartMutexInterface
183+ */
184+ private $ cartMutex ;
185+
190186 /**
191187 * @param EventManager $eventManager
192188 * @param SubmitQuoteValidator $submitQuoteValidator
@@ -211,9 +207,11 @@ class QuoteManagement implements CartManagementInterface, ResetAfterRequestInter
211207 * @param QuoteIdMaskFactory|null $quoteIdMaskFactory
212208 * @param AddressRepositoryInterface|null $addressRepository
213209 * @param RequestInterface|null $request
214- * @param RemoteAddress $remoteAddress
210+ * @param RemoteAddress|null $remoteAddress
215211 * @param LockManagerInterface $lockManager
212+ * @param CartMutexInterface|null $cartMutex
216213 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
214+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
217215 */
218216 public function __construct (
219217 EventManager $ eventManager ,
@@ -240,7 +238,8 @@ public function __construct(
240238 AddressRepositoryInterface $ addressRepository = null ,
241239 RequestInterface $ request = null ,
242240 RemoteAddress $ remoteAddress = null ,
243- LockManagerInterface $ lockManager = null
241+ LockManagerInterface $ lockManager = null ,
242+ ?CartMutexInterface $ cartMutex = null
244243 ) {
245244 $ this ->eventManager = $ eventManager ;
246245 $ this ->submitQuoteValidator = $ submitQuoteValidator ;
@@ -270,8 +269,8 @@ public function __construct(
270269 ->get (RequestInterface::class);
271270 $ this ->remoteAddress = $ remoteAddress ?: ObjectManager::getInstance ()
272271 ->get (RemoteAddress::class);
273- $ this ->lockManager = $ lockManager ?: ObjectManager:: getInstance ()
274- ->get (LockManagerInterface ::class);
272+ $ this ->cartMutex = $ cartMutex
273+ ?? ObjectManager:: getInstance () ->get (CartMutexInterface ::class);
275274 }
276275
277276 /**
@@ -397,10 +396,28 @@ protected function createCustomerCart($customerId, $storeId)
397396
398397 /**
399398 * @inheritdoc
399+ */
400+ public function placeOrder ($ cartId , PaymentInterface $ paymentMethod = null )
401+ {
402+ return $ this ->cartMutex ->execute (
403+ (int )$ cartId ,
404+ \Closure::fromCallable ([$ this , 'placeOrderRun ' ]),
405+ [$ cartId , $ paymentMethod ]
406+ );
407+ }
408+
409+ /**
410+ * Places an order for a specified cart.
411+ *
412+ * @param int $cartId The cart ID.
413+ * @param PaymentInterface|null $paymentMethod
414+ * @throws CouldNotSaveException
415+ * @return int Order ID.
400416 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
401417 * @SuppressWarnings(PHPMD.NPathComplexity)
418+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
402419 */
403- public function placeOrder ($ cartId , PaymentInterface $ paymentMethod = null )
420+ private function placeOrderRun ($ cartId , PaymentInterface $ paymentMethod = null )
404421 {
405422 $ quote = $ this ->quoteRepository ->getActive ($ cartId );
406423 $ customer = $ quote ->getCustomer ();
@@ -614,12 +631,6 @@ protected function submitQuote(QuoteEntity $quote, $orderData = [])
614631 ]
615632 );
616633
617- $ lockedName = self ::LOCK_PREFIX . $ quote ->getId ();
618- if (!$ this ->lockManager ->lock ($ lockedName , self ::LOCK_TIMEOUT )) {
619- throw new LocalizedException (__ (
620- 'A server error stopped your order from being placed. Please try to place your order again. '
621- ));
622- }
623634 try {
624635 $ order = $ this ->orderManagement ->place ($ order );
625636 $ quote ->setIsActive (false );
@@ -632,7 +643,6 @@ protected function submitQuote(QuoteEntity $quote, $orderData = [])
632643 );
633644 $ this ->quoteRepository ->save ($ quote );
634645 } catch (\Exception $ e ) {
635- $ this ->lockManager ->unlock ($ lockedName );
636646 $ this ->rollbackAddresses ($ quote , $ order , $ e );
637647 throw $ e ;
638648 }
0 commit comments