Я унаследовал 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);
}
}
Только обслуживание должно быть транзакционным. http://stackoverflow.com/questions/1079114/where-does-the-transactional-annotation-belong – JEY
Также посмотрите на отправку на codereview.stackexchange.com –
, если только некоторые из них не помечены с расширением REQUIRES_NEW, затем "вложенность" транзакции действительно не должны иметь существенного влияния. АОП просто скажет: «Да, там уже один, продолжай». (у меня нет ответа, потому что вы на самом деле не задавали никаких вопросов. Мой совет был бы концепцией «вложенности» их в изоляции, вероятно, не является основной причиной ваших проблем с производительностью.) – Affe