最近,我遇到了一篇有趣的文章,内容涉及如何使用spring存储库对数据库执行批处理操作-http://knes1.github.io/blog/2015/2015-10-19-streaming-mysql-results-using-java8-streams-and-spring-data.html,并且已经实现了使用分页的解决方案。
一切正常,但是我不了解清除entitymanager会如何影响批处理期间数据库上可能发生的其他操作。
@PersistenceContext private EntityManager entityManager; @Autowired private MyRepository myRepository;
感谢您的帮助
答案 0 :(得分:0)
Spring Entity Manager和Spring Data Repository有什么关系?如果我在Spring Data Repository上执行操作,为什么清除Spring Entity Manager会影响使用的内存?
Spring数据JpaRepository
引用了EntityManager
并使用它来实现其方法。
对于组成JpaRepository
的固定方法,您可以在SimpleRepository
清除
EntityManager
会如何影响批处理期间可能发生的其他读/写操作?
EntityManager
是一个JPA构造。所有托管引用均已连接到一个EntityManager
。这样一来,JPA实现便可以学习何时修改实体,因此需要在下一个刷新事件时进行保存。为此,EntityManager
必须跟踪其遇到的所有实体。对于典型的Web应用程序,这意味着:
EntityManager
。由于只涉及几个实体,所以对所有实体的引用都不是什么大问题。
在批处理设置中,事情通常会大不相同。 没有特殊的思想,自然的事情将是:
EntityManager
。因此,您保留了成千上万甚至数以百万计的实体引用,在许多情况下,这些引用将不再受到影响。
当EntityManager
访问其实体引用列表时,这会给内存带来压力,并影响性能。
这些操作是:
EntityManager
中引用每个已加载和持久保存的实体但是EntityManager
及其第一级缓存(它保留的实体图)也有好处:实体仅加载一次。
如果您的批次一遍又一遍地引用了一些已经存在的实体(典型的“主数据”),则不会一次又一次地加载,而每个EntityManager
只会加载一次。
因此,您可能也不想在每个已处理的行之后刷新EntityManager
。
如何创建Spring Entity Manager和Spring Data Repository的专用实例?现在,我正在使用基本的自动接线。
你不知道。
有创建专用实例的方法。
毕竟,这只是Java代码。
但是您真的不想这样做。
而是仅使用按类型生成的sing存储库实例。
它为EntityManager
注入了一个代理。
实际的EntityManager
将用于交易。
并在上述代理中的事务开始时进行交换。
这是Spring Scope Magic的一部分。
您需要做的是用@Transactional
注释您的方法,以使事务保持在合理的规模之内。
为批量处理创建单独的Spring Entity Manager和Spring Data Repository实例有意义吗?
不,我不这么认为。 这只会使事情变得复杂。