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

Java 我想最小化@Transactional的范围吗?,java,spring,jpa,transactions,annotations,Java,Spring,Jpa,Transactions,Annotations,不确定这里的“范围”是否正确 我使用Spring进行JPA事务管理(下面是Hibernate)。我执行数据库事务的方法是私有的,但因为您只能在类或数据库上设置@Transactional 由于该机制基于代理,因此只有通过代理传入的“外部”方法调用才会被拦截。这意味着“自调用”,即目标对象中调用目标对象的其他方法的方法,即使调用的方法标记为@Transactional,也不会在运行时产生实际的事务 我已经将类的公共入口点设置为@Transactional @Transactional public

不确定这里的“范围”是否正确

我使用Spring进行JPA事务管理(下面是Hibernate)。我执行数据库事务的方法是私有的,但因为您只能在类或数据库上设置@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类中,并将其公开,但作为学术观点,我想知道对公开进行重构是否会对性能有任何好处。

如果在DB上存在激烈的争论,保持事务尽可能小绝对是至关重要的——比公共和私人的区别重要得多,这本身不会影响性能和可伸缩性。所以,要实际点

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

正如大家所指出的,我们应该尽可能减少事务,以便连接可用于其他请求。 这个可以像这样重构吗

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

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

取决于事务隔离级别。使用可序列化隔离,数据库需要跟踪事务开始时的状态,以便其他事务的提交不会影响您的读取。@andri,事务什么时候开始?我想skaffman是说直到调用em.persist才开始?就数据库而言,事务只有在获得与数据库的连接时才开始。如果在调用storeData()方法之前不执行此操作,那么就数据库而言,事务开始时就是这样。在连接被包含之前,数据库没有参与,也没有被通知。我最初写这个问题时没有意识到,但是你可以在类级别设置@Transactional。所以Spring一定在做一些限制事务长度的事情。我想你可能误解了我的问题@Transactional只能存在于公共方法上,但我想问的是,我们是否应该尝试将@Transactional限制为仅做数据库工作的方法。我确实理解:我们确实应该尽可能严格地限制事务范围,如果这意味着将某些事情公开,而您更愿意将其保密,这不是世界末日。我这里有两个答案,如果我理解正确的话,它们说的是相反的东西,其他人能在这个问题上权衡一下吗?这个问题与这个问题有些关联。