重度嵌套@Transactional注释

时间:2016-03-24 14:51:28

标签: java spring jpa spring-transactions

我继承了一个Spring Java代码库,几乎从业务服务到低级DAO的所有方法都被标记为@Transactional。当某些注释从@Transactional(readOnly = false)更改为@Transactional(readOnly = true)时,我注意到它有一些严重的性能问题。它似乎也定期调用EntityManager.flush(),但除了没有它们就没有将某些对象写入数据库之外,这些调用无法解释。

我的预感是原始开发人员滥用/过度使用交易,但我不确定清理它的最佳方法。我很感谢那些比我更精通Spring 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);
    }
}

1 个答案:

答案 0 :(得分:0)

鉴于问题是“如何清理交易注释?”答案是 - 基于上述评论;

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