Closed cn-nemo closed 4 years ago
@cn-nemo 查询参数每个线程都是 new 的新对象,不会出现所谓的串的问题, 2.3.2
修复的那个问题是返回自定义 Bean 时,在单独的异步线程 Spring Data JPA 不会释放连接的问题。
@cn-nemo 查询参数每个线程都是 new 的新对象,不会出现所谓的串的问题,
2.3.2
修复的那个问题是返回自定义 Bean 时,在单独的异步线程 Spring Data JPA 不会释放连接的问题。
这个sql是用了fenix注解的,从结果看已经是串的;表现看,fenix打印日志时候参数还是对的,但是给hibernate绑参数时候串了。能不能给下思路呢,另外能否提示一下fenix给hibernate底层传参数在什么地方呢?谢谢
@cn-nemo 在 FenixJpaQuery.java 类中,doCreateQuery
方法和 doCreateCountQuery
方法分别是生成 JPA 查询和分页查询所需的 Query
对象。
你好,我写了一个简单测试,并发执行同一个fenix 的sql,两个线程循环让他们重叠,sql的入参只有id,两个线程分别传入1,0,传入id=0的应该查不出东西才对,但是却串了入参查出的非预期的结果,打印了如截图;不用fenix则不会。 说明fenix 有问题吧?
` @Test @Category(IUnionPayCategory.class) @Transactional @Rollback public void test6() throws Exception { Thread1 thread1 = new Thread1(); Thread2 thread2 = new Thread2(); thread1.start(); thread2.start();
try {
Thread.sleep(500000000);
} catch (InterruptedException e) {
System.out.println(e);
}
}
class Thread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 500000000; i++) {
organizationRep.selectTest6(1);
}
}
}
class Thread2 extends Thread{
@Override
public void run() {
for (int i = 0; i < 500000000; i++) {
Organization organization = organizationRep.selectTest6(0);
if(organization != null && organization.getId()>0){
System.out.println("-------------串了--------------id="+organization.getId());
}else{
System.out.print(".");
}
}
}
}`
@cn-nemo 嗯,我排查下看看。
@cn-nemo 嗯,我排查下看看。
这个问题是很严重的,麻烦尽快解决更新一下(是不是哪里用了多线程公共变量。。),多谢了。
@cn-nemo 找到问题了,原来 Spring Data JPA 里面所 new FenixJpaQuery
的对象是为每个 repository
查询接口方法共享的同一个对象,而代码里面把参数和 SQL 信息设置成了成员变量了,同一个 repository
查询接口方法多线程下就会有线程安全问题。
目前我已经修改了一版,目前测试没发现问题,你可以临时先使用 2.3.3-SNAPSHOT
这个快照版本,明天我再测试下,没问题了再发正式版。
@cn-nemo 找到问题了,原来 Spring Data JPA 里面所
new FenixJpaQuery
的对象是为每个repository
查询接口方法共享的同一个对象,而代码里面把参数和 SQL 信息设置成了成员变量了,同一个repository
查询接口方法多线程下就会有线程安全问题。目前我已经修改了一版,目前测试没发现问题,你可以临时先使用
2.3.3-SNAPSHOT
这个快照版本,明天我再测试下,没问题了再发正式版。
首先非常感谢及时解决,主要更要避免连带问题; 这个直接的根源点是什么呢,是同一个sql严格同时并发就会出现吗?看到有时候也不会串,问一下以便针对性测试; 2.3.3-SNAPSHOT是我自己用分支打包还是你打包放在仓库了呢?
@cn-nemo Maven 仓库远程应该有 SNAPSHOT 版本,根源点就是我上面说的原因。
@cn-nemo Maven 仓库远程应该有 SNAPSHOT 版本,根源点就是我上面说的原因。
但有时候为什么不会串
另外,这两个都获取不到版本
<!-- https://mvnrepository.com/artifact/com.blinkfox/fenix -->
<dependency>
<groupId>com.blinkfox</groupId>
<artifactId>fenix</artifactId>
<version>2.3.3-SNAPSHOT</version>
</dependency>
@cn-nemo Maven 仓库远程应该有 SNAPSHOT 版本,根源点就是我上面说的原因。
你好啊,我没有断点来测,给作者提两个测试时候注意的建议,一个是同一个线程查不同的sql;另一个是用了ThreadLocal,线程是复用的,看看是否要清除FenixQueryInfo相关的东西
@cn-nemo 都有单元测试,单元测试自行本来就是并发的,所以,第一种情况本来就是没问题的,同一个接口方法不同的 SQL 对象也在 ThreadLocal
对象里面也没问题,现在的代码 FenixQueryInfo
使用完毕后会手动 remove
掉。
@cn-nemo 都有单元测试,单元测试自行本来就是并发的,所以,第一种情况本来就是没问题的,同一个接口方法不同的 SQL 对象也在
ThreadLocal
对象里面也没问题,现在的代码FenixQueryInfo
使用完毕后会手动remove
掉。
好的,感谢。你这边测没什么问题了吧,我没有拉得到你打包的快照版本啊,是没有放到远程么
@cn-nemo 版本发了,你可以直接拉 2.3.3
的正式版。
@cn-nemo 版本发了,你可以直接拉
2.3.3
的正式版。
嗯,拉到了。可以说说有时候为什么不会串吗? 另外也发现一个兼容jpa2.2.0改字节码哪里的问题,后面再另反馈给你吧
多线程执行机制问题,可能不会串,本质上是谁先拿到 CPU 执行权,大多数时候不会同时执行一个接口方法,所以,没有问题。即时执行同一个接口查询方法,但如果不是并行的,也不会有问题,当然多个线程并发执行同一个接口方法时,如果参数相同,也不会有问题。只有在两个线程以不同参数查询同一个接口方法时,由于参数做成了成员变量,可能一个线程的参数结果覆盖了另一个参数的线程结果。就可能查询结果出现不符合预期的结果。
字节码那个是为了兼容老版本的 JPA,Spring Data JPA 每个大版本可能对它内部的接口、实现参数或者是否可公开访等问做改变,为了兼容以前的老的 Spring Data JPA,用字节码去写了。有问题你可以继续提新的 issue
我看看,如果可以建议你升级 Spring Boot 或者 Spring Data JPA 的版本到最新版本,就不会去走以前的代码了。
多线程执行机制问题,可能不会串,本质上是谁先拿到 CPU 执行权,大多数时候不会同时执行一个接口方法,所以,没有问题。即时执行同一个接口查询方法,但如果不是并行的,也不会有问题,当然多个线程并发执行同一个接口方法时,如果参数相同,也不会有问题。只有在两个线程以不同参数查询同一个接口方法时,由于参数做成了成员变量,可能一个线程的参数结果覆盖了另一个参数的线程结果。就可能查询结果出现不符合预期的结果。
字节码那个是为了兼容老版本的 JPA,Spring Data JPA 每个大版本可能对它内部的接口、实现参数或者是否可公开访等问做改变,为了兼容以前的老的 Spring Data JPA,用字节码去写了。有问题你可以继续提新的
issue
我看看,如果可以建议你升级 Spring Boot 或者 Spring Data JPA 的版本到最新版本,就不会去走以前的代码了。
说回当前问题,我理解,是不是同一个sql,多线程cpu时间片轮转时候,会串是应为第一个线程塞了参数后,时间片轮到了另一个线程,把它参数覆盖了,因为两个线程都是用同一个FenixJpaQuery对象,所以后面执行的sql都是相同的了。 所以串与不串取决于塞参数和执行sql有没有时间片中断线程穿插,我理解对么? 另外建议作者也可看其他地方有没有多线程共用一个对象的情况
嗯,理解是对的。跟 JPA 接入和实现无关的其它地方都是自己的代码了,写的时候就考虑的了,应该是没问题的,这个问题本质上还是对 JPA 里面的对象机制不太了解引起的。
嗯,理解是对的。跟 JPA 接入和实现无关的其它地方都是自己的代码了,写的时候就考虑的了,应该是没问题的,这个问题本质上还是对 JPA 里面的对象机制不太了解引起的。
加油,挺看好这个工具,只要测好稳定了,大家就会放心用了。
你好。如下图2.2.0版本中相同sql在并发中两个线程的查询参数串了。
1、不知道作者是否已发现此问题?
2、然后在最新版本v2.3.2修复的“修复了在异步多线程情况下,返回自定义实体 Bean 类型时,JDBC 连接未释放的问题,老版本可以使用 @Transactional 注解解决;”是否包含解决这个问题呢?
麻烦帮忙看看,谢谢。