开发者社区> 问答> 正文

怎么避免多个 session 同时操作 Collection ???

写了一个简单的点评网站抓取的程序

今天后台碰到了:

ERROR org.grails.web.errors.GrailsExceptionResolver - HibernateException occurred when processing request: [POST] /cities/yelp/94349
llegal attempt to associate a collection with two open sessions. Collection : [com.ttt.website.backend.domains.BeautySpots.beautySpotsImages#dianping-48232229]. Sta
ktrace follows:
rg.springframework.orm.hibernate4.HibernateSystemException: Illegal attempt to associate a collection with two open sessions. Collection : [com.ttt.website.backend.
omains.BeautySpots.beautySpotsImages#dianping-48232229]; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open se

  1. Collection : [com.ttt.website.backend.domains.BeautySpots.beautySpotsImages#dianping-48232229]
    at com.ttt.website.backend.tools.dianping.DianPingRestaurantsScraper$_saveRestaurants_closure1.doCall(DianPingRestaurantsScraper.groovy:135)
    at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:90)
    at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:87)
    at com.ttt.website.backend.tools.dianping.DianPingRestaurantsScraper.saveRestaurants(DianPingRestaurantsScraper.groovy:133)
    at com.ttt.website.backend.tools.dianping.DianPingRestaurantsScraper.scrape(DianPingRestaurantsScraper.groovy:41)
    at com.ttt.website.backend.controllers.CitiesController.$tt__yelp(CitiesController.groovy:388)
    at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
  2. by: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [com.ttt.website.backend.domains.BeautySp

ts.beautySpotsImages#dianping-48232229]

   ... 8 common frames omitted

有一个类:BeautySpots,它是表示每一个餐馆,在这个类里面,引用了另外一个表:
beautySpotsImages

这个是保存的餐馆的图片

异常就是说有两个 session 在同时访问这个 Collection

这个程序是单线程跑的

我贴一下代码(Groovy的代码)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
restaurant.description = description.toString()

BeautySpots.withTransaction([propagationBehavior: TransactionDefinition.PROPAGATION_REQUIRES_NEW,

 isolationLevel: TransactionDefinition.ISOLATION_READ_COMMITTED]) {
restaurant.save(failOnError: true, flush: true) //这里出的问题

}

savedRestaurantsAmount++

if (isNewRestaurant) {

imageUrls = getImageUrls(restaurant.referTo, shopId)
// 下载图片在下面的方法: ScraperUtil.saveRestaurantImages

if (!ScraperUtil.saveRestaurantImages(restaurant, creator, restaurant.referTo, imageUrls, 0, 70)) {

    restaurant.delete()
    return
}

}
restaurant.completionProgress = POIUtil.getCompletionProgress(restaurant)
BeautySpots.withTransaction([propagationBehavior: TransactionDefinition.PROPAGATION_REQUIRES_NEW,

 isolationLevel: TransactionDefinition.ISOLATION_READ_COMMITTED]) {
restaurant.save(failOnError: true)

}

展开
收起
爵霸 2016-02-29 16:02:15 4140 0
1 条回答
写回答
取消 提交回答
  • 需要通过同步解决,单机就采用synchronized关键字解决;多机就是分配式数据同步了,可以采用redis同步或者zookeeper

    2019-07-17 18:50:26
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载