Use loadForUpdate when creating payments inside onNotify

Created on 31 January 2024, 12 months ago
Updated 5 August 2024, 5 months ago

Problem/Motivation

Following up on issue #3339344 🐛 Fix placing the order twice Fixed , I previously mentioned that:

No need for loadForUpdate here since we're not saving the order itself.
LoadUnchanged works fine.

However, this is not true, we do need to lock the order when we create payments even when we do not modify the order entity itself.

Here's a scenario where loadUnchanged would fail:

  1. onNotify started execution before onReturn
  2. onNotify started creating the payment
  3. onReturn started execution and managed to lock the order before onNotify finished
  4. onNotify finished, and the paymentOrderUpdater tried to update the order
  5. When the paymentOrderUpdater tried to save the order, the order was still locked by onReturn
  6. OrderLockedSaveException was thrown
  7. onReturn finished

With the above scenario, we end up with two payments and an OrderLockedSaveException.

The solution is to use loadForUpdate inside both onReturn and onNotify, and to save the order at the end of onNotify to force the order to get updated, leaving this job to the paymentOrderUpdater, would throw the following exception:
EntityStorageException: Failed to start the session because headers have already been sent

🐛 Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024