gpt4 book ai didi

java - Spring Transactional 减慢了整个过程

转载 作者:搜寻专家 更新时间:2023-10-31 20:17:21 24 4
gpt4 key购买 nike

我正在尝试分析我有两个类(class)的情况。一类是 ProcessImpl,它是起点并在内部调用其他子事务。我不知道出了什么问题。processImpl 正在导入一些东西并将相关数据写入数据库。

Specs

Spring-orm 版本:3.2.18.RELEASE。

JDK 版本:1.8。

Db:H2(在任何数据库上都记录了相同的性能)。

Issue

如果我从 ProcessImpl.processStage() 中删除 @Transactional,该过程需要 ~ 50 秒如果我从 ProcessImpl.processStage() 保留 @Transactional,该过程需要 ~ 15 分钟。不知道为什么会这样。长期以来,我一直在努力解决这个问题,但没有运气。请查看下面的代码。

要求:完整的 processStage() 应该完成或完全回滚,即使其中一个子事务失败。

仅供引用:我也收到很多消息,例如:“参与现有交易”。试图通过将 propagation=Propagation.NESTED 添加到 processStage() 来解决这个问题,但没有成功。

ProcessImpl Class.

public class ProcessImpl {

/*This is the big transaction that calls other transactional stuff from MyServiceImpl
* This is starting point you can say for the process...
*
* If we remove @Transactional from here the process is lightning fast
* With transactional : 15minutes
* Without transactional : 50 seconds
* */
@Transactional
public void processStage(){
MyServiceImpl mp = new MyServiceImpl();
//do some stuff
mp.doWork1();

//do more work
mp.doWork2();

}

}

MyServiceImpl Class

class MyServiceImpl{

@Transactional
public void doWork1(){
Object o = doChildWork();
// and more stuff
//calls other class services and dao layers
}

@Transactional
public void doWork2(){
//some stuff
doChildWork2();
doChildWork();
//more work
}

@Transactional
public Object doChildWork(){
return new Object(); //hypothetical, I am returning list and other collection stuff
}

@Transactional
public Object doChildWork2(){
return new Object(); //hypothetical, I am returning list and other collection stuff
}

}

此外,这里会出现自调用问题,这在事务性中是不可取的吗?

最佳答案

很难猜测您的代码中到底发生了什么,但是这些是可能的问题:

锁定数据库级别。当您在 doWork1()doWork2() 中更新同一个 DB 对象时,可能会发生这种情况。由于这两种方法都在一个事务中执行,因此在 doWork2() 完成之前,不会提交在 doWork1() 中完成的更新。这两种方法都可能尝试锁定同一个数据库对象并等待它。从技术上讲,它可以是任何数据库对象:表中的行、索引、整个表等。

分析您的代码并尝试找出可以锁定的内容。您还可以在方法运行时查看数据库事务日志。所有流行的数据库都提供有助于查找有问题的地方的功能。

在 Hibernate 上下文刷新期间放慢速度。 如果您更新太多对象,ORM 引擎(假设是 Hibernate)必须将它们下沉并保存在内存中。从字面上看,Hibernate 必须具有更新对象的所有旧状态和所有新状态。有时它不是以最佳方式执行此操作。

您可以使用调试来指示这一点。尝试找到最慢的地方并检查那里到底调用了什么。我可能猜想它会在 hibernate 更新缓存状态时变慢。

还有一个问题。我看到您在 processStage() 期间使用构造函数创建了 MyServiceImpl。我建议你用 spring Autowiring 来替换这段代码。首先,您使用它的方式不是它的设计使用方式,但理论上这也会以某种方式影响执行。

will I get self invocation issue, which is not advisable in Transactional?

不,忽略所有注释也能正常工作。在 doWork2() 中调用 doChildWork()doChildWork2() 将被视为标准 java 调用(spring 无法添加任何“魔法”,只要您直接调用它们即可)。

关于java - Spring Transactional 减慢了整个过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46214484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com