Как я могу синхронизировать через аспекты Java, определенные вокруг метода? - PullRequest
2 голосов
/ 15 ноября 2011

У меня есть транзакционный метод Hibernate "doImportImpl", который работает многопоточным. Однако некоторые записи необходимо импортировать последовательно, поэтому структура кода примерно такая:

public RecordResult doImportImpl(String data) {
    RecordResult result = new RecordResult();
    .. do some data processing ..
    String recordIdentifier = getIdentifier(data);
    synchronized(recordIdentifier) {
       process record;
    }
    return result;
}

Существует другой метод транзакции, который также имеет идентификатор записи и не может работать параллельно с импортом записи. Поэтому он также синхронизируется по «идентификатору записи».

public void autoProcess(String data) {
    String recordIdentifier = getIdentifier(data);
    synchronized(recordIdentifier) {
       List<Record> records = dao.queryDatabase(recordIdentifier);
       for (Record r : records) {
           autoprocess record;
       }
    }
}

Вот проблема: иногда кажется, что метод autoProcess() начинает выполняться ПОСЛЕ того, как синхронизированный блок из doImportImpl() завершается, но ДО транзакции фиксируется. Таким образом, из-за уровня изоляции tx вызов dao.queryDatabase() еще не видит импортированные записи в базе данных.

Как мне убедиться, что синхронизированная блокировка удерживается на всем протяжении «оператора возврата», включая все аспекты вызова метода (которые обрабатывают управление транзакциями Hibernate)? Достаточно ли поместить оператор return в синхронизированный блок?

Спасибо Саймон Нидербергер

1 Ответ

0 голосов
/ 15 ноября 2011

Вы должны использовать блокировки базы данных вместо synchronized блоков. Когда вы запрашиваете запись по recordIdentifier, используйте select for update или то, что доступно для вашей базы данных.

Кроме того, для меня это запах синхронизации на String с.

...