嵌套严重的@事务性注释



我继承了一个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);
    }
}

如果问题是"如何清理事务注释?",答案将基于以上注释;

  1. 不要在DAO中使用事务注释,只在Services中使用(@组件)
  2. 确保DAO仅通过服务层

最新更新