Here is the drill: our whole processing stack for orders is particularly sensitive to race conditions. During the checkout process, especially, it is not unlikely for the same order to be processed twice. The two common cause for this are:
(1) People clicking on a button twice
(2) Payment gateways or other external services wanting to affect the status of the order at the same time as the customer
The only solution for this is to implement locking. This locking needs to be:
- pessimistic: the order needs to be locked way upfront, as soon as it is loaded, and only unlocked when finally saved.
- unconditional: because of the richness of the Drupal pipeline, there is no way to know upfront that an order is not going to be modified (and saved) down the road.
We made sure that core supports this type of use case #1185780: Make transactions more flexible and useful (which is in 7.x and will be released with 7.8). Now it is time for this to actually happen.
Comments
Comment #1
damien tournoud commentedHere is probably the most minimal patch for this. It's not the end of the road, but it's better then nothing, and I would like to put that in front of everyone as soon as possible.
Here are some of the things we need to figure out:
This passes the test suite.
Comment #2
rszrama commentedWith this patch applied, I can generate a PDOException using the following code at /devel/php:
The exception message is: There is already an active transaction in db_transaction() (line 2479 of /includes/database/database.inc).
I've done what I can to try and debug this, but I'm not having any success.
Comment #3
rszrama commentedOk, the error I was getting is already solved in Drupal 7.x-dev, so as soon as 7.8 or later is released, there won't be any issue. I'm going to go ahead and commit this patch, and if anyone runs into the db_transaction() error I mentioned above, they can just update to 7.x-dev for the fix.
Comment #4
carn1x commentedDo you mean update to Commerce dev or Core dev?
Comment #5
rszrama commentedCore dev, b/c it's a bug in Drupal itself not Commerce.
Comment #6
carn1x commentedSorry to get a little off-topic, are you aware of a clean method to take Drupal core stable to dev, and then back again once the next stable is released? Is this even a good idea or should I just wait until 7.8? I've floated the question in a few places, nothing but tumbleweed! Thanks :)
Comment #7
rszrama commentedI suppose it really depends on what kind of changes have gone into core. The only danger is if you were to update to a version that made a schema change but then a later patch undid the schema change or something. You can review the changelog before updating to dev, but I didn't experience any problems. Buyer beware. ; )
And if it's too much risk, we'll have a 7.8 the first Wednesday of September. They're doing predictable point releases now.
Comment #8
j0rd commentedI just upgraded to latest -dev and not I'm getting this error with devel module enabled. I get this error when attempting payment with authorize.net
This is a blocker for my site, as I can't process any transactions now.
Additionally even with this error, it appears my hook_order_paid_in_full which I would assume if we're using transaction locking, should not happen.
Digging into it.
Update: Disabled devel and it doesn't appear to happen after I tried again. I did get another interesting bug related to PHP errors on checkout which needs to be addressed. http://drupal.org/node/1251840
Comment #9
j0rd commentedUpgrading to Drupal 7.x-dev fixed the problem for me, as per:
http://drupal.org/node/1225846#comment-4851154
Comment #10
rfayRelated in commerce_migrate_ubercart: #1252278: Commerce Order pessimistic locking causes deadlocks in migrations