swa*_*ntu 5 java spring transactions transactional spring-orm
我试图分析一下我有两个班级的情况.一个类是ProcessImpl,它是起点并在内部调用其他子事务.我不知道什么是错误的.processImpl正在导入一些东西并将相关数据写入数据库.
眼镜
Spring-orm版本:3.2.18.RELEASE.
JDK版本:1.8.
Db:H2(记录任何db相同的性能).
问题
如果我@Transactional从ProcessImpl.processStage()过程中删除需要~50秒
如果我保持@Transactional从ProcessImpl.processStage()过程需要〜15分钟.不知道为什么会这样.我一直试图解决这个问题,但没有运气.请看下面的代码.
要求:
完成processStage()应完成或完全回滚,即使其中一个子事务失败.
Fyi:我也收到很多消息:"参与现有交易".试图通过添加propagation=Propagation.NESTED到processStage()但没有工作来克服这个问题.
ProcessImpl类.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
MyServiceImpl类
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
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我将在这里获得自我调用问题,这在Transactional中是不可取的?
很难猜测你的代码到底发生了什么,但是这些是可能的问题:
锁定数据库级别。
当您在doWork1()和 中更新相同的数据库对象时,可能会发生这种情况doWork2()。由于这两种方法都在一个事务中执行,因此在完成doWork1()之前不会提交内部完成的更新doWork2()。这两种方法可能会尝试锁定同一个 DB 对象并等待它。从技术上讲,它可以是任何 DB 对象:表中的行、索引、整个表等。
分析您的代码并尝试找出可能被锁定的内容。您还可以在方法运行时查看数据库事务日志。所有流行的 DB 都提供有助于查找有问题的地方的功能。
在休眠上下文刷新期间减慢速度。如果您更新太多对象,ORM 引擎(比如 Hibernate)必须接收它们并将它们保存在内存中。从字面上看,Hibernate 必须具有更新对象的所有旧状态和所有新状态。有时它不是以最佳方式做到这一点。
您可以使用调试来指示这一点。尝试找到最慢的地方并检查那里到底调用了什么。我可能猜测它在休眠更新缓存状态时会变慢。
还有一个问题。我看到您MyServiceImpl在processStage(). 我建议您通过弹簧自动装配替换此代码。首先,您使用它的方式不是它设计的使用方式,但理论上这也会以某种方式影响执行。
我会遇到自调用问题,这在事务中是不可取的吗?
不,它会很好地忽略所有注释。doChildWork()和doChildWork2()inside 的调用doWork2()将被视为标准的 java 调用(只要您直接调用它们,spring 就无法向它们添加任何“魔法”)。
| 归档时间: |
|
| 查看次数: |
1627 次 |
| 最近记录: |