Хочу ли я минимизировать объем @Transactional? - PullRequest
1 голос
/ 30 апреля 2009

Не уверен, что здесь термин «область действия» правильный.

Я использую Spring для управления транзакциями JPA (с Hibernate внизу). Мой метод для преобразования транзакции базы данных является частным, но поскольку вы можете установить @Transactional только для класса или для открытого метода

Поскольку этот механизм основан на прокси, будут перехватываться только внешние вызовы методов, поступающие через прокси. Это означает, что «самовывоз», то есть метод в целевом объекте, вызывающий какой-либо другой метод целевого объекта, не приведет к реальной транзакции во время выполнения, даже если вызванный метод помечен @Transactional!

Я установил общедоступную точку входа класса как @ Transactional.

@Transactional
public void run(parameters) {
    //First non-database method, takes a decent amount of time
    Data data = getData();
    //Call to database
    storeData(data);
}

private storeData(data) {
    em.persist(data);
}

Это плохая практика? Spring сохраняет открытую транзакцию дольше, чем необходимо здесь? Я думал о том, чтобы переместить метод storeData () в класс DAO и сделать его общедоступным, но в качестве академического соображения я хотел бы знать, принесет ли рефакторинг для public какой-либо выигрыш в производительности.

Ответы [ 3 ]

1 голос
/ 30 апреля 2009

Область действия транзакции не действует, пока ваш код не выполнит что-то, что взаимодействует с контекстом транзакции, в данном случае это метод storeData (). Тот факт, что getData () не является транзакционным, не должен влиять на производительность параллелизма вашего кода, поскольку любая блокировка базы данных произойдет только при достижении storeData ().

1 голос
/ 30 апреля 2009

Если есть большая конкуренция на БД, то, безусловно, крайне важно поддерживать как можно меньшие транзакции - гораздо важнее, чем публичные и частные различия, которые сами по себе не влияют на производительность и масштабируемость. Так что будьте практичны ...!

0 голосов
/ 10 сентября 2018

Как все отметили, мы должны поддерживать как можно меньшую транзакцию, чтобы соединение оставалось доступным для другого запроса. Может ли это быть рефакторинг как это

public void run(parameters) {
  Data data = getData();
  storeData(data);                                                             
 }

@Transactional
public storeDate(data){em.persist(data)}
...