gpt4 book ai didi

hibernate - 如何不使用flush进行更新:true

转载 作者:行者123 更新时间:2023-12-02 14:23:03 25 4
gpt4 key购买 nike

我必须更新一个包含街道的250.000行表。只要我用

street.save(flush:true) 

它可以工作,但是速度非常慢( 2 hours for 250.000)。如果我省略 flush:true子句,它似乎可以快速运行,但是根本不更新。

是否需要进行总体提交,保存250.000次保存后刷新并执行该操作?

彼得

最佳答案

使用domainInstance.save(flush: true)会强制SQL查询在该时刻执行。这并不意味着此时已将更改提交给数据库,但是它确实会执行一些SQL。

使用交易方法

我认为值得尝试的第一次尝试(因为它是最简单的)是确保调用save()的方法是@Transactional。这使Hibernate可以使用其最佳判断(尽可能长时间地延迟SQL),而不必强制刷新Hibernate session 。

import org.springframework.transaction.annotation.Transactional

class SomeController {

@Transactional
def save() {
def streets = /* Some GORM query */

streets.each {
/* Make updates here */
it.save() /* No flush needed because the method is transactional */
}
}
}

使用updateAll()

只有在以下情况下,才有另一个选项可用:
  • 您不需要更新关联的属性。
  • 在此更新之前,您不会对同一域实例进行任何其他更新。

  • 第二个标准是微妙的,可以使您发疯。 DetachedCriteria.updateAll(Map)没有看到未提交的更改。例如,如果您手动进行更改...
    someInstance.foo = 'bar'
    someInstance.save(flush: true)

    ...然后使用 updateAll()在同一实例上进行操作, updateAll()不会知道您之前所做的事情。

    因此,如果情况允许,您可以使用 updateAll():
    @Transactional
    def save() {
    def streets = Street.where { /* a GORM where query */}

    streets.updateAll([propertyA: valueA, propertyB: valueB])
    }

    如您所知, updateAll()根据属性名称/属性值 Map修改每个合格的域类实例。

    关于hibernate - 如何不使用flush进行更新:true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34655727/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com