2016-03-24 3 views
0

Я унаследовал Spring Java-коду, где она кажется почти любым методом от бизнес-службы до DAO низкого уровня, помечены @Transactional. У меня есть некоторые серьезные проблемы с производительностью, которые, как я заметил, несколько смягчены, когда определенные аннотации изменены с @Transactional (readOnly = false) на @Transactional (readOnly = true). Он также имеет периодические вызовы EntityManager.flush(), которые не могут быть объяснены, за исключением того, что некоторые объекты не записываются в БД без них.Тяжело вложенные аннотации @Transactional

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

Ниже приведен сокращенный пример только одного сегмента кода. Есть и другие, более сложные, чем при 5-6 уровнях вложенных транзакций.

// MVC Controller REST Service 
@Controller 
@RequestMapping("/service") 
public class Group { 
    @Inject private GroupService groupService; 

    public @ResponseBody Object update(@RequestBody Group group) { 
     return groupService.update(group); 
    } 
} 

// Business service 
@Service 
public class GroupService { 
    @Inject private GroupDAO groupDao; 
    @Inject private AuditService auditService; 

    @Transactional(readOnly=false) 
    public Group update(Group group) { 
     Group groupToUpdate = groupDao.get(group.getId()); 
     // Do magic 
     groupDao.persist(groupToUpdate); // Shorthand to call EntityManager.persist() 
     auditService.logUpdate(group); 
     return groupToUpdate; 
    } 
} 

// DAO 
@Repository 
public class GroupDAO extends AbstractDAO { 
    @Transactional(readOnly=true) 
    public Group get(Long id) { 
     return entityManager.find(Group.class,id); 
    } 
} 

// Auditing service 
@Component 
public class AuditService { 
    @Inject AlertDAO alertDao; 

    @Transactional(readOnly=false) 
    public void logUpdate(Object o) { 
     Alert alert = alertDao.getFor(o); 
     // Do magic 
     alertDao.update(alert); 
     alertDao.flush() // Shorthand for EntityManager.flush() but WHY??? 
    } 
} 

// DAO 
@Repository 
public class AlertDAO extends AbstractDAO { 
    @Transactional(readOnly=true) 
    public Alert getFor(Object forObj) { 
     // Magic here 
     return entityManager.find(Alert.class,foundId); 
    } 

    @Transactional(readOnly=false) 
    public void update(Alert a) { 
     // Magic here 
     entityManager.merge(a); 
    } 
} 
+2

Только обслуживание должно быть транзакционным. http://stackoverflow.com/questions/1079114/where-does-the-transactional-annotation-belong – JEY

+0

Также посмотрите на отправку на codereview.stackexchange.com –

+4

, если только некоторые из них не помечены с расширением REQUIRES_NEW, затем "вложенность" транзакции действительно не должны иметь существенного влияния. АОП просто скажет: «Да, там уже один, продолжай». (у меня нет ответа, потому что вы на самом деле не задавали никаких вопросов. Мой совет был бы концепцией «вложенности» их в изоляции, вероятно, не является основной причиной ваших проблем с производительностью.) – Affe

ответ

0

Учитывая, что вопрос заключается в «как очистить аннотации транзакций?» ответ будет основан на вышеупомянутых комментариях;

  1. Не используйте транзакции аннотаций в DAO, только в Услуги (@Components)
  2. Убедитесь, что объекты DAO вызываются только через сервис-слой .
Смежные вопросы