最近,我遇到了一篇有趣的文章,介绍了如何使用spring存储库在数据库上执行批处理操作-- http://knes1.github.io/blog/2015/2015-10-19-streaming-mysql-results-using-java8-streams-and-spring-data.html和我使用分页实现了解决方案。
所有操作都很好,但是我不明白清理实体管理器如何影响在批处理期间数据库上可能发生的其他操作。
@PersistenceContext私有的EntityManager entityManager;@Autowired私有的MyRepository myRepository;
谢谢你的帮忙
发布于 2018-06-24 05:06:23
Spring实体管理器和Spring数据仓库之间的关系是什么?如果我在上执行操作,为什么清除Spring实体管理器会影响使用的内存?
Spring JpaRepository
具有对EntityManager
的引用,并使用它来实现其方法。对于构成JpaRepository
的固定方法,您可以在SimpleRepository
中找到实现
清除
EntityManager
如何影响批处理过程中可能发生的其他读/写操作?
EntityManager
是一个JPA结构。所有托管引用都连接到一个EntityManager
。这样,JPA实现就可以了解实体何时被修改,因此需要保存下一个刷新事件。为了做到这一点,EntityManager
必须跟踪它遇到的所有实体。对于典型的web应用程序,这意味着:
EntityManager
。因为只涉及几个实体,保存对所有实体的引用并不是什么大问题。
在批处理环境中,事情往往是完全不同的。如果没有特别的思考,自然的事情是:
EntityManager
。因此,您保留了数千甚至数百万次对实体的引用,这些实体在许多情况下不会再被触及。这会给内存带来压力,并且在EntityManager
访问其实体引用列表时也会影响性能。这类行动是:
EntityManager
中引用但是EntityManager
和它的第一级缓存(它保存的实体映射)也有好处:实体只加载一次。如果您的批处理一次又一次地引用一些已经存在的实体(典型的“主数据”),那么它不会一次又一次地加载,但每个EntityManager
只加载一次。因此,您可能也不希望在每个处理过的行之后刷新您的EntityManager
。
如何创建Spring实体管理器和Spring数据仓库的专用实例?现在我用的是基本的自动布线。
没有,有一些方法可以创建专用的实例。毕竟,它只是Java代码。但你真的不想这么做。相反,只需使用每个类型生成的sing存储库实例即可。它会被注入一个EntityManager
的代理。实际的EntityManager
将存在于事务中。并在上面提到的代理内部的事务开始时交换。这是Spring范围魔术的一部分。
您需要做的是用@Transactional
对您的方法进行注释,以便事务保持在合理的大小之内。
创建用于批处理的Spring实体管理器和Spring数据仓库的单独实例是否有意义?
不,我想不是这样的。这只会让事情变得复杂。
https://stackoverflow.com/questions/51002080
复制相似问题