Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate orders with same Quote Id at same time with few time difference. #13952

Closed
amitvishvakarma opened this issue Mar 5, 2018 · 76 comments
Labels
Area: Cart & Checkout Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P0 This generally occurs in cases when the entire functionality is blocked. Progress: done Reported on 2.3.x Indicates original Magento version for the Issue report. Reported on 2.4.x Indicates original Magento version for the Issue report. Reproduced on 2.4.x The issue has been reproduced on latest 2.4-develop branch

Comments

@amitvishvakarma
Copy link
Contributor

amitvishvakarma commented Mar 5, 2018

Preconditions

  1. Ability to process requests at same time. (in our case, we had use 2 different Client's system.)

Steps to reproduce

  1. Login as a User
  2. Add items to cart and proceed through checkout.
  3. Select Any payment method. Not click on place order button
  4. Now login to the same account in another system.
  5. And proceed to checkout with the same items. Not click on place order button.
  6. Now you have to click on place order at the same time with both the systems.
    Observe order confirmation screen of both systems. (usually first time you will get an error about constraint violations. Try to repeat steps 1-6 again. Issue reproduces 100% from the second attempt)

Depending on your infrastructure, this bug may be challenging to reproduce. It requires all of the "Place order" button clicks to be processed concurrently by Magento. You will not see the bug if Magento is processing requests sequentially (as the second request will reference a cart ID that no longer exists).

Expected result
A single order has been placed.
Alternatively, if multiple requests are unavoidable: Only the first request to be processed.

Actual result
Two different orders have been placed with very few seconds as time difference with same quote Id.

@magento-engcom-team magento-engcom-team added Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed labels Mar 5, 2018
@magento-engcom-team
Copy link
Contributor

@amitcedcoss, thank you for your report.
We've acknowledged the issue and added to our backlog.

@magento-engcom-team magento-engcom-team added Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release labels Mar 5, 2018
@sunilit42
Copy link
Contributor

I am working on this at #dmcdindia

@sunilit42
Copy link
Contributor

It happens when you click same time on the button.
@magento-engcom-team There is two way we can do

  1. use flock, for that we need to create one lock file quote wise when you click on that button
  2. Either create one table and make an entry while click on submit and remove when order placement or fail order.

Let me know which way you want to process.

@timbaker1991
Copy link

Just to further this, we have the issue and it appears to affect PayPal orders mainly- though this may be coincidence (using the baked in Braintree support this is). Is there anything we could use as a hot fix do you know?

@amitvishvakarma
Copy link
Contributor Author

@magento-engcom-team any update regarding our issue?

@buituanbg
Copy link

@magento-engcom-team I got the same issue too. The quote is same ID but it created 5 orders today. So I appreciate any updates for this.

@tzy1992
Copy link

tzy1992 commented Aug 7, 2018

@magento-engcom-team Any update on this issue? The issue occur randomly and it created multiple order on my site mainly from using Cash on Delivery payment method.

@buituanbg
Copy link

@tzy1992 I had a quick fixing solution. let me know if you want to view that.

@tzy1992
Copy link

tzy1992 commented Aug 7, 2018

@buituanbg Please share the fix with me. Thank you

@timbaker1991
Copy link

@buituanbg Please could you share it on here for us all to see if possible.

@buituanbg
Copy link

buituanbg commented Aug 7, 2018

Hi @tzy1992 and @timbaker1991
I created an observer as below:
app/code/TB/FixDuplicateOrder/Observer/OrderPlacebefore.php
'<?php
namespace TB\FixDuplicateOrder\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class OrderPlacebefore implements ObserverInterface
{
protected $_responseFactory;
protected $_url;

public function __construct(
    \Magento\Framework\App\ResponseFactory $responseFactory,
    \Magento\Framework\UrlInterface $url
) {
    $this->_responseFactory = $responseFactory;
    $this->_url = $url;
}

public function execute(\Magento\Framework\Event\Observer $observer)
{
	$event = $observer->getEvent();

	$order = $observer->getEvent()->getOrder();
	$quoteID = $order->getQuoteId();
	$objectManager = \Magento\Framework\App\ObjectManager::getInstance();  
	$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
    $connection = $resource->getConnection();
    $tableName = $resource->getTableName('sales_order');
    $selectedTime = date('Y-m-d h:i:s');
	$endTime = strtotime("-15 seconds", strtotime($selectedTime));
	$last15Sec = date('Y-m-d h:i:s', $endTime);

    echo $sql = "SELECT * FROM `".$tableName."` WHERE `quote_id` = ".$quoteID." and `created_at` >= '$last15Sec'";
    if($result = $connection->fetchRow($sql)){
    	$customerBeforeAuthUrl = $this->_url->getUrl('checkout');
        $this->_responseFactory->create()->setRedirect($customerBeforeAuthUrl)->sendResponse();
        exit();
    }
    //var_dump($result);
    //echo  "Hello Testing ";
    //die();
}

}'
app/code/TB/FixDuplicateOrder/etc/events.xml

app/code/TB/FixDuplicateOrder/registration.php
'<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'TB_FixDuplicateOrder',
DIR
);'
This event observer will prevent order created on the same quote in past 15 secrets because as my detect main issue in about 15 secret it create order with same quote id. I created this from 01-Jul and I didn't get any duplicate order after that. Also all other process relate to place order is fine there isn't any issues.
Hope my solution can help. Let me know if any.
Thanks,
tuan

@tzy1992
Copy link

tzy1992 commented Aug 7, 2018

@buituanbg Thanks for sharing the fix, for the event you are using sales_order_place_before ?

@buituanbg
Copy link

yes, I used sales_order_place_before event.

@tzy1992
Copy link

tzy1992 commented Aug 9, 2018

@buituanbg I am still getting duplicated order after apply the fix, both order created at the exact date and time.

@magento-engcom-team Any update regarding this issue?

@buituanbg
Copy link

buituanbg commented Aug 9, 2018

@tzy1992 it seems you got other case. Let me know if you need support to debug.

@misha-kotov
Copy link

@tzy1992 @buituanbg @timbaker1991 @amitcedcoss
Does anyone have a guess why this happens on production systems? I doubt real shoppers are checking out in different browsers/devices trying to cause race conditions on your stores. We have heard a theory that when the system is overloaded, order submission may be kicking users back into checkout even if the order is created, and submitting again creates a duplicate order. Currently the quote does get invalidated, but there is still a window of opportunity of a couple seconds where duplicate orders can get created.
Just trying to get to root cause so we can fix appropriately.

@rauberdaniel
Copy link

rauberdaniel commented Dec 13, 2018

General question: What would happen if there would be a UNIQUE constraint set to the quote_id column of the sales_order table. That would prohibit the creation of duplicate orders for the same quote in any case, however, I’m not sure if it has any problematic side effects or what the result on customer side would be in such a case.

(But in general I feel like this constraint should be set anyway?)

@DependencyHell
Copy link

@rauberdaniel I think the quote_id cannot be UNIQUE as if one order is canceled (getting back from paypal without validation for example), the cart (quote_id) remains the same and can be used in another order.

@developer-vtnetzwelt
Copy link

Any update on this issue?

@mgomma
Copy link

mgomma commented Feb 25, 2019

Any update on that issue .. it happens when create order from custom code .. not happen when place order regularly.

@LSERRE
Copy link

LSERRE commented Feb 28, 2019

This issue occurs randomly on one of our 2.3.0 project. Any update on this issue?

@m2-community-project m2-community-project bot moved this from Dev In Progress to Pull Request In Progress in High Priority Backlog Feb 16, 2022
@m2-community-project m2-community-project bot moved this from Pull Request In Progress to Ready for Development in High Priority Backlog Feb 16, 2022
@m2-community-project m2-community-project bot moved this from Ready for Development to Dev In Progress in High Priority Backlog Feb 17, 2022
@m2-community-project m2-community-project bot moved this from Ready for Development to Dev In Progress in High Priority Backlog Feb 17, 2022
@m2-community-project m2-community-project bot moved this from Dev In Progress to Pull Request In Progress in High Priority Backlog Feb 18, 2022
@wgabka
Copy link

wgabka commented Feb 21, 2022

Hello all. I have notice issue with duplicate orders with the same quote id. All of your cases can have different origin but it's generally related to bad architecture of exception handling and not using database transaction or locking mechanizm in \Magento\Quote\Model\QuoteManagement::submitQuote.

Problem is in this code fragment.

        try {
            $order = $this->orderManagement->place($order);
            
            $quote->setIsActive(false);
            $this->eventManager->dispatch(
                'sales_model_service_quote_submit_success',
                [
                    'order' => $order,
                    'quote' => $quote
                ]
            );
            $this->quoteRepository->save($quote);
        } catch (\Exception $e) {
            $this->rollbackAddresses($quote, $order, $e);
            throw $e;
        }

author don't take in consideration that something can go wrong after line

$order = $this->orderManagement->place($order);

and this is huge mistake because we have event there and magento can have a ton of plugins on place after.
What is happen if something goes wrong? Quote is not save and marked as not active. That means on frontend we will have the same quote active and users can try to create another order with the same quote id.

In general I implement quick clean fix to handle most of the cases in our project with checks is order with quote_id has been placed in second line of the method using di for validateQuote.

this->submitQuoteValidator->validateQuote($quote);

I cannot share the code but it's pretty straightforward to implement.

For people which are strugling with concurency I would suggect to add plugin around submitQuote to set lock on quote_id before and release lock after including my fix for checking is order with quote already exists.

@fiko
Copy link
Contributor

fiko commented Feb 25, 2022

Hello All,

I tried to fix the issue, so I setIsActive to false once customer placing the order. And in order to handle (in case there is an error while placing order), I set active to true again.

Hope it's for good, I've test it at the same time almost 30 times. and it works well.

@engcom-Alfa
Copy link
Contributor

This ticket had an internal Jira, and due to various reasons that Jira got processed and cancelled.
In order to further follow-up and take it forward, we have created a new issue - 35833, and it has already created PR 35139 linked.
Hence, we can refer these tickets for future updates.

Thanks for your all of your contributions and collaborations here!

fiko added a commit to fiko/magento2 that referenced this issue Aug 7, 2022
fiko added a commit to fiko/magento2 that referenced this issue Aug 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Cart & Checkout Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P0 This generally occurs in cases when the entire functionality is blocked. Progress: done Reported on 2.3.x Indicates original Magento version for the Issue report. Reported on 2.4.x Indicates original Magento version for the Issue report. Reproduced on 2.4.x The issue has been reproduced on latest 2.4-develop branch
Projects