我正在使用spring数据和apache camel的项目,我们有2个数据库,Sql Server和带JTA的Oracle。问题出现是因为我需要从一个大文件中插入数据(大约10000000条记录),所以我决定使用批量插入作为:
@PersistenceContext(unitName="persistenceUnitSql")
EntityManager em;
public void insertBatch() {
em.getTransaction().begin();
for (int i = 1; i <= 1000000; i++) {
Point point = new Point(i, i);
em.persist(point);
if ((i % 10000) == 0) {
em.getTransaction().commit();
em.clear();
em.getTransaction().begin();
}
}
em.getTransaction().commit();
}
但是发生了这个问题:
A JTA EntityManager cannot use getTransaction()
任何帮助......
答案 0 :(得分:1)
自我控制JTA交易似乎比预期的要困难得多。我通常使用的一种解决方法是使用单独的服务&#34;哪一个插入,你在该方法上设置REQUIRES_NEW事务传播策略,所以它看起来像:
class FooService {
private PointPersister pointPersister;
@Transactional(propagation=REQUIRED)
public void insertBatch() {
List<Point> points = new ArrayList<Point>(10000);
for (int i = 1; i <= 1000000; i++) {
points.add(new Point(i,1));
if ((i % 10000) == 0) {
pointPersister.insertPointBatch(points);
}
}
}
}
class PointPersisterImpl implements PointPersister {
@PersistenceContext
private EntityManager em;
@Transactional(propagation=REQUIRES_NEW) // in a separate txn
public void insertPointBatch(List<Point> points) {
// persist points
}
}
您还可以做出其他选择,以避免处理麻烦且容易出错的手动事务处理。 Spring Batch是可能的解决方案之一。
答案 1 :(得分:0)
我通过以下方式解决了这个问题:
@PersistenceUnit(unitName="persistenceUnitSql")
// from persistence xml <persistence-unit name="persistenceUnitSql" transaction-type="JTA">
private EntityManagerFactory emf;
@Autowired
private JtaTransactionManager transactionManagerSqlServer;
// from application-context.xml
//<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManagerSqlServer" />
public List<Point> insertBatch(List<Point> datos) {
try {
UserTransaction transaction = transactionManagerSqlServer.getUserTransaction();
transaction.begin();
EntityManager em = emf.createEntityManager();
for (Point punto : datos) {
em.persist(punto);
}
transaction.commit();
em.close();
} catch (NotSupportedException e) {
LOGGER.error(e);
} catch (SystemException e) {
LOGGER.error(e);
} catch (SecurityException e) {
LOGGER.error(e);
} catch (IllegalStateException e) {
LOGGER.error(e);
} catch (RollbackException e) {
LOGGER.error(e);
} catch (HeuristicMixedException e) {
LOGGER.error(e);
} catch (HeuristicRollbackException e) {
LOGGER.error(e);
}
return datos;
}