我正在尝试处理大约1千万条MySQL DB1
的记录,然后将它们保存到MySQL DB2
。
我使用大约50个线程来实现这一目标。生产者从中获取500
条记录
MySQL DB1
一次,然后将它们放入队列。大约有50位消费者将对其进行处理,然后将其插入MySQL DB2
。
在大多数情况下,它可以正常工作。但是对于大约5万条记录,它失败了。
分析日志后,我发现抛出了CannotCreateTransactionException
:
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed:
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:450) ~[spring-orm-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378) ~[spring-tx-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
此网站上有一些类似的问题,我已经尝试了其中的一些问题:
MyRepository.saveAll()
引发异常后,重试5次
将BasicDataSource
与较大的maxActive
和setValidationQuery
,setTestOnBorrow
一起使用:
BasicDataSource dataSource = new BasicDataSource();
dataSource.setMaxActive(100);
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("***");
dataSource.setUsername("***");
dataSource.setPassword("***");
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("SELECT 1");
dataSource.setMaxActive(30);
它仍然不起作用。我该如何解决?
答案 0 :(得分:0)
我进行了很多搜索并尝试了不同的解决方案。
最后,将配置更改为此后,该异常不再显示:
@Bean
public DataSource poiDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setMaxActive(100);
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("**");
dataSource.setUsername("**");
dataSource.setPassword("**");
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("SELECT 1");
dataSource.setMaxActive(30);
dataSource.setRemoveAbandoned(true);
dataSource.setMaxWait(60000);
dataSource.setTimeBetweenEvictionRunsMillis(300000);
dataSource.setMinEvictableIdleTimeMillis(300000);
dataSource.setTestWhileIdle(true);
dataSource.setLogAbandoned(true);
return dataSource;
}