Spring JPA 使用EntityManager时如何配置多数据源的事物管理
来源:互联网 发布:投资软件靠谱吗 编辑:程序博客网 时间:2024/06/05 11:19
在使用Spring JPA插入数据时 一般使用CrudRepository自带的save方法。但是最近需要定时将云集群里的Scala程序计算的一些指标数据通过消息队列获取后存入本地DB,每次百万级的插入,使用该方法需要3H57min。查看JPA的源码想找个批量插入的方法提高速度。
在Spring Data JPA的源码中看到
Iterable save(Iterable entities);
查看其源码发现,其实现还是通过遍历逐个插入
save源码:
/* * (non-Javadoc) * @see org.springframework.data.jpa.repository.JpaRepository#save(java.lang.Iterable) */ @Transactional public <S extends T> List<S> save(Iterable<S> entities) { List<S> result = new ArrayList<S>(); if (entities == null) { return result; } for (S entity : entities) { result.add(save(entity)); } return result; }
通过在网上查找,发现可以通过Spring注解 @PersistenceContext() 实现事物管理 EntityManager 来完成批量插入,具体方法如下
package com.foundersc.ifc.adviser.decision.dao;import org.springframework.transaction.annotation.Transactional;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import java.util.List;/** * Created by weimiantong on 17/6/28. */public abstract class AbstractDao<T> { @PersistenceContext() protected EntityManager em; @Transactional("") public void batchInsert(List<T> list) { for (int i = 0; i < list.size(); i++) { em.persist(list.get(i)); if (i % 100 == 0) { em.flush(); em.clear(); } } } @Transactional() public void batchUpdate(List<T> list) { for (int i = 0; i < list.size(); i++) { em.merge(list.get(i)); if (i % 100 == 0) { em.flush(); em.clear(); } } }}
该方法在service工程里单独跑单元测试是没问题的,百万级的插入缩短到2H23min。但是当把单元测试通过的Service工程maven依赖到webapp工程进行使用时,由于webapp工程使用了多个Service需要配置多个数据源。启动报了如下错
Context initialization failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jcSignalDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 6: entityManagerFactory,entityManagerFactory125,entityManagerFactoryFinancial,wxentityManagerFactory,entityManagerFactory_kh,entityManagerFactoryCommunity
jcSignalDao 需要一个事物管理,但是在spring-jpa.xml 中却配置了6个entityManagerFactory 的beam。导致不知道用哪一个。
解决方法:
通过 @Qualifier(“entityManagerFactoryCommunity”) 注解指定目标数据源的管理器即可, 正确写法如下:
package com.foundersc.ifc.adviser.decision.dao;import lombok.Data;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.transaction.annotation.Transactional;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import java.util.List;/** * Created by weimiantong on 17/6/28. */@Datapublic abstract class AbstractDao<T> { //@PersistenceContext(name = "entityManagerFactoryCommunity") @Autowired @Qualifier("entityManagerFactoryCommunity") public EntityManagerFactory emfc; @Transactional("transactionManagerCommunity") public void batchInsert(List<T> list) { EntityManager em = emfc.createEntityManager(); for (int i = 0; i < list.size(); i++) { em.persist(list.get(i)); if (i % 100 == 0) { em.flush(); em.clear(); } } em.close();//不关闭可能导致连接池异常 } @Transactional("transactionManagerCommunity") public void batchUpdate(List<T> list) { EntityManager em = emfc.createEntityManager(); for (int i = 0; i < list.size(); i++) { em.merge(list.get(i)); if (i % 100 == 0) { em.flush(); em.clear(); } } em.close(); }}
阅读全文
0 0
- Spring JPA 使用EntityManager时如何配置多数据源的事物管理
- spring多数据源+事物管理
- spring多数据源+事物管理
- spring-boot 使用 spring-data-jpa多数据源配置
- 【DB】【Spring】多数据源事物配置
- 同一节点多数据源的事物管理(配置多个事物实现)
- jpa+spring配置多数据源
- Spring JPA多数据源配置
- jpa+spring配置多数据源
- jpa+spring配置多数据源
- jpa+spring配置多数据源
- spring data jpa 配置多数据源
- spring 多数据源 事物
- Spring Boot + Spring Data JPA项目配置多数据源
- Spring Boot,Spring Data JPA多数据源支持配置
- spring jpa 事物配置
- Spring Boot学习(七)之Web应用使用Spring-data-jpa多数据源配置
- spring 事物控制---多数据源与 atomikos 分布式事务配置(接之前未完成的部分)
- Java学习之非访问修饰符
- nyoj 过河问题
- 机器学习: 训练集、验证集、测试集关系
- Java中的进制
- 42canvas元素
- Spring JPA 使用EntityManager时如何配置多数据源的事物管理
- Java计算两个具体日期相差的天数
- easyui----行内编辑---有单价 输入数量自动计算总金额
- LeetCode 389. Find the Difference
- 使用GreenDao3.0实现一个记事本App
- Java参数传递方式
- FILTER:progid:DXImageTransform.Microsoft.Gradient使用
- Kali Linux进行内网攻击--》使用arpspoof
- java基于StringBuilder自己实现myArrayList