настраиваемое время ожидания весенней транзакции - PullRequest
0 голосов
/ 11 января 2019

У меня есть транзакционный метод с фиксированным таймаутом. Есть ли способ сделать время ожидания транзакции настраиваемым через, например, application.yml?

@Transactional(propagation = Propagation.REQUIRED, timeout = TIMEOUT)
public String doStuff(String id) throws Exception {
    service.doSomeStuff
}

1 Ответ

0 голосов
/ 12 января 2019

Поскольку мы не можем присвоить значение переменной атрибуту аннотации Java, для программной установки @Transactional timeout лучше всего переопределить AbstractPlatformTransactionManager#determineTimeout().

Предположим, вы используете JpaTransactionManager, новый менеджер выглядит как код ниже. Это позволяет установить таймаут для каждой транзакции. Мы можем использовать имя TransactionDefinition для идентификации транзакции, которая в случае декларативной транзакции Spring имеет имя по умолчанию в формате FullyQualifiedClassName.MethodName.

public class FooTransactionManager extends JpaTransactionManager {

    private Map<String, Integer> txTimeout = new HashMap<String, Integer>();

    public <T> void configureTxTimeout(Class<T> clazz, String methodName, Integer timeoutSecond) {
        txTimeout.put(clazz.getName() + "." + methodName, timeoutSecond);
    }

    //The timeout set by `configureTxTimeout` will have higher priority than the one set in @Transactional
    @Override
    protected int determineTimeout(TransactionDefinition definition) {;
        if (txTimeout.containsKey(definition.getName())) {
            return txTimeout.get(definition.getName());
        } else {
            return super.determineTimeout(definition);
        }
    }   
}

Затем настройте PlatformTransactionManager:

@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
    final FooTransactionManager transactionManager = new FooTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    transactionManager.configureTxTimeout(Foo.class, "doStuff", 10);
    transactionManager.configureTxTimeout(Bar.class, "doStuff", 20);
    transactionManager.configureTxTimeout(Bar.class, "doMoreStuff", 30);
    //blablabla

    return transactionManager;
}

Приведенные выше коды предназначены только для демонстрации. В действительности вы можете использовать @Value для чтения значения из внешних свойств (например, application.yml) во время конфигурации.

...