关于Spring JpaRepository方法线程安全

ashishgupta_mca

我很好奇spring jparepository方法是否是线程安全的,然后阅读了stackflow文章(Spring Data(JPA)Repository线程安全吗?(又名SimpleJpaRepository线程安全))。从那里,我了解到存储库方法是线程安全的,然后我制作了一个POC来测试线程安全。我让一个存储库说FormRepository来对“表单”实体进行CRUD操作,这就是对JpaRepository的扩展。我从DAO中简单地调用了100个线程来创建表单对象,然后手动设置其ID,然后保存“表单”对象。

以下是供参考的代码:-

@Repository
public interface FormRepository extends JpaRepository<Tbldynamicform, Long>     {

Tbldynamicform save(Tbldynamicform tblform);

@Query("SELECT max(tblform.formid) FROM Tbldynamicform tblform")
Optional<Integer> findMaxId();

}
......End of Repository above and start of DAO below...

@Component
public class DynamicFormDAO implements DynamicFormDAO {

@Inject
private FormRepository formRepository;

public void testThreadSafety() throws Exception {
    List<Callable<Integer>> tasks = new ArrayList<>(100);
    for (int i = 0; i < 100; i++) {

        tasks.add(() -> {
            try {

                Tbldynamicform tbldynamicform = new Tbldynamicform();//Set  all the required fields for form
                if (tbldynamicform.getFormid() == null)
                    tbldynamicform.setFormid(findFormID());
                Tbldynamicform form = formRepository.save(tbldynamicform);
                return form.getFormid();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        });
    }
    ExecutorService executor = Executors.newFixedThreadPool(100);
    executor.invokeAll(tasks);

}

private int findFormID() throws Exception {
    Optional<Integer> id = formRepository.findMaxId();
    if (id != null && id.isPresent() && id.get() != null) {
        int generatedId = id.get().intValue();
        return ++generatedId;
    }
    return 0;
}
}

当我这样做时,我以为一切都可以正常工作,因为表单存储库方法是线程安全的,但是以某种方式我在日志中多次获取了sql dataintegrityviolationexception,从而导致插入多个记录失败。以下错误供参考:

org.springframework.dao.DataIntegrityViolationException:无法执行语句;SQL [n / a];约束[“ PUBLIC.TBLDYNAMICFORM(FORMID)上的主键”;SQL语句:插入到Tbldynamicform(clientid,copyfromexisting,creatationdate,formdesc,formmode,formname,formtemplate,formtitle,procutype,status,formid)值(?,?,?,?,...)

这使我开始思考这是线程安全问题还是其他问题?据我了解,我在dao中创建的所有“ tbldynamicform”对象都将保留在线程堆栈中。只有formRepository将位于堆存储中,并且如果formrepository方法是线程安全的,则必须在数据库中插入100条记录,而不会出现任何问题。

如果我执行setId并保存在同步块中,则一切正常,但这不是我的意图,并且如果存储库方法是线程安全的,则不是必需的。

专家,有什么帮助吗?

阿维亚德

您的保存任务不是原子的-两个线程可能会在其中一个保存新实体之前获取相同的最大id。

然后,即使存储库的save方法是线程安全的,也无济于事。

maxId是线程安全的,save是线程安全的,但是每个线程的可运行内部的方法都不是线程安全的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

类方法线程安全吗?

来自分类Dev

以下方法线程安全吗

来自分类Dev

这种方法线程安全吗?

来自分类Dev

我的getStatement方法线程安全吗?

来自分类Dev

从实例方法线程调用静态方法安全吗?

来自分类Dev

关于Spring MVC测试API的model()。attribute()方法的询问

来自分类Dev

java.lang.Class方法线程安全吗?

来自分类Dev

如何在JAVA中使静态方法线程安全?

来自分类Dev

jaxrs 1.1(WLP 8.5)注释方法线程安全吗?

来自分类Dev

C#此方法线程安全吗?

来自分类Dev

此静态方法线程安全还是需要同步

来自分类Dev

具有局部变量的全局方法线程安全

来自分类Dev

GenericObjectPools借款对象方法线程安全吗?

来自分类Dev

C ++方法线程

来自分类Dev

关于线程安全和JPA EntityManager

来自分类Dev

关于线程安全和JPA EntityManager

来自分类Dev

关于字符串线程安全的示例

来自分类Dev

C ++类方法线程

来自分类Dev

Java ArrayList.add()方法线程可安全用于纯并行添加吗?

来自分类Dev

Spring mongoTemplate线程安全吗?

来自分类Dev

spring @transactional线程安全吗?

来自分类Dev

Spring:如何使线程安全@Component?

来自分类Dev

Spring JdbcTemplate线程安全吗?

来自分类Dev

关于spring Rowmapper,mapRow

来自分类Dev

关于Spring queryforlist

来自分类Dev

关于并行POSIX线程

来自分类Dev

关于Laravel 5.1安全

来自分类Dev

开启枚举方法线程错误

来自分类Dev

在Spring bean中处理线程安全的方法及其优点和缺点