В этом коде:
@Override
public boolean updateEntity() {
final boolean[] success = {false};
final PersistentEntityStore entityStore = manager.getPersistentEntityStore();
entityStore.executeInTransaction(
new StoreTransactionalExecutable() {
@Override
public void execute(@NotNull final StoreTransaction txn) {
doUpdateThrowsException();
success[0] = true;
}
});
return success[0];
}
Каков наилучший подход, чтобы можно было избежать использования массива boolean?
@marstran невозможно.
Вообще говоря, причина этой ошибки в том, что вы передаете обратный вызов, поэтому нет гарантии, что код будет выполнен немедленно. Вполне может быть, что он возвращает успех, но код выполняется асинхронно, а затем выходит из строя. В данном конкретном случае это не проблема, но в общем случае это очень плохо.
Лучший способ исправить это - исправить API - например, возьмите Callable<T> в качестве аргумента и верните Future<T> из executeInTransaction.




Вы должны использовать изменяемый объект в качестве держателя статуса. AtomicBoolean должен вам подойти.
Очевидно, что «лучшим» подходом было бы иметь возможность использовать возвращаемое значение executeInTransaction, но поскольку вы не можете повлиять на эту часть ...
Я также надеюсь, что вы на 100%. executeInTransaction - это операция блокировки - иначе этот код работать не будет.
Если это проблема параллелизма (и вы не знаете, когда будет выполнен код), вам, вероятно, следует использовать CompletionStage<Boolean> или какой-либо другой вид Future / Promise. Таким образом, вы можете отличить, если что-то вышло из строя или еще даже не запустилось (ваш массив или AtomicBoolean будут ложными в любом случае, и вам понадобится второй, чтобы решить, началась ли ваша транзакция).
Если этот код синхронный, кажется, должен быть более прямой способ проверить, было ли выброшено то исключение, которое вы пытаетесь обнаружить. У этого executeInTransaction нет способа вернуть данные или хотя бы сбои?
StoreTransactionalExecutable - это класс из библиотеки JetBrains, поэтому я не контролирую его, так как он работает, выдает исключение, если во время транзакции произошла ошибка, таким образом, установка успеха в строке означает, что транзакция завершилась успешно. И да, поток блокируется.
Если это вызывает исключение, зачем вам флаг? Разве вызывающий абонент не может понять это в зависимости от того, было ли у него исключение или нет?
@ maio290 Вы не можете установить значение локальной переменной из анонимного класса.