Problem
There is a problem in the function commerce_marketplace_cart_order_load_multiple
in commerce_marketplace_cart.module
where the last order_group
id is found with SELECT order_group FROM commerce_order ORDER BY order_group DESC LIMIT 1
.
If two users add a product in the cart at the same time, they might get the same order_group.
Proposed resolution
Create a new table order_group_ids
with a primary key, auto-increment, id
column.
Instead of retrieving the order_group
id and increment it, insert a new row in the new table order_group_ids
and use LAST_INSERT_ID()
and the equivalent in PostgreSQL to retrieve the id.
MySQL documentation on LAST_INSERT_ID()
:
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Remaining tasks
This is a quick fix that works, but should really be optimized.
For example :
- add a column orders
in the table order_group_ids
to store the serialized orders for this order_group
- if (!empty($orders))
: add the order to the column
- else
: change db_query
with db_insert
to insert and retrieve the id at the same time
Data model changes
Table order_group_ids created.
Comments
Comment #2
jordan.gillet CreditAttribution: jordan.gillet commentedHere is the patch.
Thanks for the review.
Comment #3
jordan.gillet CreditAttribution: jordan.gillet commentedComment #4
GrimreaperHello,
Thanks for the patch.
As I don't know the Commerce marketplace module, here is a review on styles and good practices.
Missing blank line after <?php opening.
Missing ending point.
For hook_update_N, you should tell what the hook does and not Implements hook_update_N. This comment will be shown in the terminal when using Drush or in the update page to inform on what the update does.
Missing ending point.
Code would be easier to read if you have this line on multiple lines.
Same comment for readability.
Why not using the db_insert() function?
Also, after posting a patch, you should change the status to "needs review", and maybe remove the assignation the issue.
Your patch should have been named commerce_marketplace-fix_race_condition-2850718-2.patch (missing the comment number and be more precise on underscores).
PS: comment written before comment 3 was posted :)
Comment #5
jordan.gillet CreditAttribution: jordan.gillet commentedComment #6
jordan.gillet CreditAttribution: jordan.gillet commentedComment #7
jordan.gillet CreditAttribution: jordan.gillet commentedHello,
Thank you for the review.
I have updated the patch with the good practices and some refactoring.
I didn't use the
db_insert()
function because the keyworddefault
is sent instring
and doesn't work in PostgreSQL.Comment #8
jordan.gillet CreditAttribution: jordan.gillet commentedComment #9
jordan.gillet CreditAttribution: jordan.gillet commentedFixed space in file name.
Comment #10
farhadhf CreditAttribution: farhadhf as a volunteer commentedAre you sure this is the right module?! We don't even have a file called
commerce_marketplace_cart.module
. Actually, this module does not have the directory/modules/cart/
at all! I'm closing this issue.