我继承了一个Spring Java代码库,从业务服务到低级DAO,几乎每个方法都用@Transactional标记。它有一些严重的性能问题,当某些注释从@Transactional(readOnly=false)更改为@Transactional时,我注意到这些问题在一定程度上得到了缓解。它似乎还定期调用EntityManager.flush(),这一点无法解释,只是某些对象在没有它们的情况下无法写入数据库。
我的直觉是,最初的开发人员正在滥用/过度使用事务,但我不确定解决这一问题的最佳方法。我将感谢那些比我更精通春季交易的人的建议。
下面是一个简化的代码段示例。还有比这复杂得多的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);
}
}
如果问题是"如何清理事务注释?",答案将基于以上注释;
- 不要在DAO中使用事务注释,只在Services中使用(@组件)
- 确保DAO仅通过服务层