I tried to debug it and also read many article about deadlock prevention but could not get this. I have used synchronization, to make thread safe a block of code on the basis of `accountNumber`.
I am getting this `Transaction` object from an API and I want to lock my code on the basis of what the `Transaction` object contain. `Transaction` object contains info like debit/credit account number, amount etc.
Two threads should not be executed `executeTransaction` method simultaneously if there is any common `accountNumber` between them.
Here, `lockedAccount` is storing all accounts that are currently locked and two methods for locking and unlocking an `accountNumber`.
DAO / Repository layer.
for more information ,
my **accountDetails** table in database have three columns,
I'm not a JPA/Hibernate expert, but that's not how I'd use the EntityManager. Why unwrap the session, why call saveOrUpdate etc.?
Get the objects via the EntityManager, update their state, and you should be done (as long as the entity is managed by the EntityManager, it will know when you modify it, and will save it without any extra calls when the transaction completes).
Also, I have never had to do this magic with ordering entity loading, and mixing in synchronisation via wait-notify. You can use optimistic locking (by adding a version number to the entity and to the DB table). It will sometimes fail, but that's a fact of life: someone has committed a transaction that changed the state of your object, so you're working on stale data. How you handle that optimistic lock failure depends on the business logic: most probably you'd have to propagate the exception and make the top-level call fail, e.g. reporting it to the user or returning an error code on your REST API.
Someone makes a call to do something to Account A.
The code in LockAccount (should be lockAccount) adds 'A' to the lockedAccounts Set.
The lock on lockedAccounts is released and the work is started on account 'A'.
Someone else comes in and tries to do something to Account A.
They get the lock on the Set, and then sit in the loop waiting for 'A' to disappear from the Set.
The original user finishes and now calls unlockAccount.
They then sit there waiting on the lock on lockedAccounts as it is currently being used by the other thread that is waiting for Account A to be removed.