I have a Hibernate transactional method “doImportImpl” which runs multi-threaded. Certain records however need to be imported in sequence, so the code structure is roughly like this:
public RecordResult doImportImpl(String data) {
RecordResult result = new RecordResult();
.. do some data processing ..
String recordIdentifier = getIdentifier(data);
synchronized(recordIdentifier) {
process record;
}
return result;
}
There is a different transaction method which also has the record identifier and cannot run in parallel to the record import. It therefore is also synchronized on ‘record identifier’.
public void autoProcess(String data) {
String recordIdentifier = getIdentifier(data);
synchronized(recordIdentifier) {
List<Record> records = dao.queryDatabase(recordIdentifier);
for (Record r : records) {
autoprocess record;
}
}
}
Here’s the problem: it seems that sometimes that the method autoProcess() starts to run AFTER the synchronized block from doImportImpl() is finished, but BEFORE the transaction is committed. So, due to tx isolation level, the call to dao.queryDatabase() does not yet see the imported records on the database.
How do I make sure the synchronized lock is held all the way through the “return statement” including all aspects around the method call (which handle Hibernate transaction management)? Is it sufficient to put the return statement into the synchronized block?
Thanks
Simon Niederberger
You have to use database locks instead of
synchronizedblocks. When you query a record by therecordIdentifieruseselect for updateor what’s available for your database.Also, for me it’s smells to synchronize on a
Strings.