Duplicate payment via Stripe after concurrent update exception

Aleh Z


I have a custom logic that allows erp users to pay some invoices using stored Stripe tokens. But I ran into a related problem while editing this invoice by another user and making a payment to another at the same time.
The pseudo code of the actions is as follows:
1) The user A opens the invoice in edit mode and enters some data
2) User B clicks the pay button and User A save form
2.a) there is a default logic with creating an account.payment and its posting.

account_payment = self.env['account.payment'].sudo().create({
'amount': self.amount_total,
'payment_date': self.invoice_date or fields.Date.context_today(self),
'invoice_ids': [],
'payment_type': 'inbound',
'payment_method_id': self.env['account.payment.method'].search(
[('payment_type', '=', 'inbound'), ('code', '!=', 'sepa_direct_debit')],
'partner_type': 'customer',

2.b) After that, the _compute_amount method was automatically started to change the amounts of invoice

After that, I get an exception "ERROR: failed to serialize access due to simultaneous update" in console with explanation "ERROR odoo_db odoo.sql_db: invalid request: UPDATE "account_move" SET to "write_uid" = 2,...." and 2 payments received in Stripe.

I know about erp logic related to retry failed transaction if exception.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY. 

Question is how to process this case on erp to not lost any data from failed transaction, because payment was already send to Stripe

Maybe someone has faced similar problems and knows how to solve them?

PS. I thought about doing cr.commit() right before sending the request to stripe and cr.commit() right after the request. But I'm not sure if this is the best choice.