A multi-thread use scenario for Aurelius' work

Imagine a Point of Sales implementation example and we have class Tinvoice for the "invoice" and a class Tcustomer for the "customer info" of each invoice. Both are saved to tables "invoices" and "customers" in the database.
For each new invoice that we process, the Tcustomer object is saved by the TObjectmanager using the following:

Customer := Manager.Find<TCustomer>(CustomerId);

and if Customer does not exist in the database then a new Tcustomer is created followed by

Manager.Save(Customer);

and we continue to save the Tinvoice that has a pointer to TCustomer.
Everything is OK with single process work.....

Lets imagine now that we have to process simultaneously a big number of such invoices and we will do that using Tparallel library in different threads. The possibility to have two different threads to process simultaneously a different invoice with the same Tcustomer is high. Both threads will try to save the same Tcustomer in the table customers that with a unique key does not allow it.

What is the Aurelius way to deal with this situation?
a) Each thread has its own TobjectManager and issues: Find, Save, handle an insert error, retry find,save,handle....
b) One TobjectManager for all the threads, with a Find, Save function with Tmonitor for only one thread at the same time to deal with Tcustomer and different TobjectManagers in each thread for Tinvoice
c) Forget threads, we have time to wait the process of all invoices in a single thread
d) Any other idea?

Hi, just my 2c

If you have all needed info for the customer including the primary key you could just never use Find. Always create the customer object and use Replicate

That way if the Customer exists in the database it will be loaded. If not then it will be created.

Regards,

Thank you for your answer
Replicate is ok, if the id of the class is also the unique index key of the table. We can have also the following where replicate does not work:

Customer := Manager.Find<TCustomer>.Where(Linq['uniqueprop'] = 'aValue')

So, you are proposing a different TobjectManager per thread. My concern is that the same object can be persistent too in an other thread's TobjectManager already. And I am dealing with exceptions if an other thread managed to insert in the meantime the same Tcustomer.

Replicate is ok, if the id of the class is also the unique index key of the table

Yes, true. Replicate would be usefull only if you know the primary key in advance (so, do not work for generated sequences or guids)

So, you are proposing a different TobjectManager per thread

Yes. Usually you must have a different Connection for each thread, anyway. I guess it's possible to share a ObjectManager with locks but not the natural aproach as it would mostly defeat the threads purpose.

In cenarios where Replicate can't be used, dealing with exceptions seems to be, in my opnion, the way to go (and not bad at all).

Regards,

TObjectManager is not thread-safe. Never use the same manager from different threads. Each thread must have its own TObjectManager instance.

2 Likes