[英]Heavily nested @Transactional annotations
I have inherited a Spring Java codebase where it seems pretty much every method from the business service down to the low level DAOs are tagged with @Transactional. 我继承了一个Spring Java代码库,其中似乎从商务服务到底层DAO的几乎所有方法都使用@Transactional进行了标记。 It has some severe performance issues that I noticed are mitigated somewhat when certain annotations are changed from @Transactional(readOnly=false) to @Transactional(readOnly=true).
当某些注释从@Transactional(readOnly = false)更改为@Transactional(readOnly = true)时,我注意到有些严重的性能问题得到了缓解。 It also seems to have periodic calls to EntityManager.flush() that can't be explained except that certain objects do not get written to the DB without them.
它似乎也有对EntityManager.flush()的定期调用,除非某些对象没有它们就无法写入数据库,否则无法解释。
My hunch is that the original developers are misusing/overusing transactions, but I'm not sure of the best approach to clean this up. 我的直觉是原始开发人员正在滥用/过度使用事务,但是我不确定清除此问题的最佳方法。 I would appreciate advice from those more well-versed in Spring Transactions than me.
我会比从我那些更精通Spring Transactions的人那里得到的建议大加赞赏。
A reduced example of just one segment of the code follows. 下面是仅一段代码的简化示例。 There are others much more complex than this with 5-6 levels of nested transactions.
还有其他比这复杂得多的嵌套事务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);
}
}
Given that the question is "how to clean up transaction annotations?" 假设问题是“如何清理交易注释?” the answer would be - based on the above comments;
答案将是-根据上述评论;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.