Update same record by worker and cause transaction locking

Hi,

I am running heavily using worker and for backend service to synchronize to webservice, mostly for stock.shipment.out table. However, there is a problem which sometime it happen to update same row data but different field.
It may happen, worker update and user update same time or it may update same time by different worker.

May I know there function to check the record is lock in worker? because once happen InFailedSqlTransaction, it will take take to rollback and release the transaction by Postgres.

Here I attached the error log for reference:

EXCEPTION(most recent call first)
SerializationFailure: could not serialize access due to concurrent update

  File "src/wms/background_transaction.py", line 191, in _send
    result = execute_()
  File "src/omni_jubelio/background_transaction.py", line 545, in _execute_jubelio_request_shipment
    if to_save:
  File "trytond/model/descriptors.py", line 33, in newfunc
    return self.func(owner, *args, **kwargs)
  File "trytond/model/modelstorage.py", line 1854, in save
    cls.write(*sum(
  File "trytond/model/modelsql.py", line 159, in wrapper
    return func(cls, *args, **kwargs)
  File "trytond/model/modelsql.py", line 1041, in write
    cursor.execute(*table.update(columns, update_values,
  File "trytond/backend/postgresql/database.py", line 72, in execute
    cursor.execute(self, sql, args)
InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block

  File "trytond/worker.py", line 119, in run_task
    task.run()
  File "trytond/ir/queue.py", line 177, in run
    getattr(Model, self.data['method'])(
  File "trytond/model/modelview.py", line 774, in wrapper
    return func(cls, records, *args, **kwargs)
  File "src/wms/background_transaction.py", line 304, in send
    result = rec._send()
  File "src/wms/background_transaction.py", line 200, in _send
    self.save()
  File "trytond/model/descriptors.py", line 31, in newfunc
    return self.func(owner, [instance], *args, **kwargs)
  File "trytond/model/modelstorage.py", line 1854, in save
    cls.write(*sum(
  File "trytond/model/modelsql.py", line 159, in wrapper
    return func(cls, *args, **kwargs)
  File "trytond/model/modelsql.py", line 1012, in write
    cls.__check_domain_rule(
  File "trytond/model/modelsql.py", line 1267, in __check_domain_rule
    wrong_ids = test_domain(ids, domain)
  File "trytond/model/modelsql.py", line 1252, in test_domain
    cursor.execute(
  File "trytond/backend/postgresql/database.py", line 72, in execute
    cursor.execute(self, sql, args)

pg_locks provides a view on the locks but I doubt you could really use it.

Indeed your design must take into account such case and be prepare to replay it if necessary.

Synchronization of systems are hard to do it correctly especially when one is transactional like Tryton.
Usually it is better to make small and quick transaction that are committed frequently like we do in the account_payment_* modules.