我想最小化@Transactional的范围吗?

时间:2009-04-30 15:19:13

标签: java spring jpa transactions annotations

不确定'范围'是否是正确的术语。

我正在使用Spring进行JPA事务管理(下面是Hibernate)。我预先形成数据库事务的方法是私有的,但是因为你只能在类或public method上设置@Transactional

  

由于此机制基于代理,因此只会拦截通过代理进入的“外部”方法调用。这意味着'自调用',即目标对象中调用目标对象的其他方法的方法,即使被调用的方法用@Transactional标记,也不会在运行时导致实际的事务!

我已将该类的公共入口点设置为@Transactional。

@Transactional
public void run(parameters) {
    //First non-database method, takes a decent amount of time
    Data data = getData();
    //Call to database
    storeData(data);
}

private storeData(data) {
    em.persist(data);
}

这是不好的做法吗? Spring是否在这里需要更长时间的开放交易?我正在考虑将storeData()方法移动到DAO类并将其公开,但作为学术观点,我想知道对公共重构是否会有任何性能优势。

3 个答案:

答案 0 :(得分:1)

如果数据库存在激烈争用,那么保持交易尽可能小是绝对至关重要的 - 比公共与私有区别更重要,这本身不会影响性能和可扩展性。所以,务实......!

答案 1 :(得分:1)

在您的代码执行与事务上下文交互的操作之前,事务范围无效,在本例中为storeData()方法。 getData()是非事务性的这一事实不应影响代码并发性能,因为任何数据库锁定只会在达到storeData()时发生。

答案 2 :(得分:0)

每个人都指出,我们应该使事务尽可能小,以使连接对于其他请求仍然可用。 可以这样重构吗

public void run(parameters) {
  Data data = getData();
  storeData(data);                                                             
 }

@Transactional
public storeDate(data){em.persist(data)}