7

I am starting to see "Could not synchronize database state with session" exceptions in my logs and I'm having a hard time reproducing it. Sometimes it works fine... I am seeing two exceptions (they are happening at different times):

ERROR JDBCExceptionReporter - Deadlock found when trying to get lock; try restarting transaction ERROR PatchedDefaultFlushEventListener - Could not synchronize database state with session org.hibernate.exception.LockAcquisitionException: could not update: [com.myapp.School#1911]

And

ERROR PatchedDefaultFlushEventListener - Could not synchronize database state with session org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.myapp.School#1905]

Here is the method where they are thrown:

def populateFriends(ArrayList<FriendView> friends, User user) {

    friends.eachWithIndex { friendView, index ->

        def friend = Friend.findByFriendId(friendView.id) ?: new Friend()
        def schoolName = friendView.schoolName
        def school = null
        if (schoolName) {
            school = School.findByName(schoolName) ?: new School(name: schoolName).save(flush:true)
        }
        if (school) {
            // add to user's school list
            user = User.get(user.id)
            user.addToSchools(school)
            user = user.merge(flush: true)
            user.save(flush: true)

            friend.school = school
        }
        friend.save(flush: true)
    }
}

I've been at this all day and I'd really appreciate any help.

RyanLynch
  • 2,987
  • 3
  • 35
  • 48
  • Can you post your whole School domain here - 2) why are you doing user = user.merge(flush: true) – Sudhir N Jun 27 '12 at 06:03
  • Have you tried user.refresh()? When I experience some wierd behavior I usually refer to this post: http://stackoverflow.com/questions/536601/what-are-your-favorite-grails-debugging-tricks or to be more precise, the answer with a try save. – marko Jun 27 '12 at 07:02
  • 1
    But he should really try to figureout why does this happen and what is the source of the problem, I wouldn't do a workaround untill I know why does this happen at the first place. – Sudhir N Jun 27 '12 at 07:17
  • 1
    Where does this code "live" - in controller, transactional service or what? How about a full stack trace, or at least which line is causing the exception? How is this code being triggered - e.g. a single request from a browser, integration test, multiple simultaneous requests? – Jon Burgess Jun 27 '12 at 10:15
  • This code is in a transactional service. I've narrowed down the problem a bit.. it seems that these exceptions are only thrown when multiple simultaneous requests are hitting the method. Does that help? – RyanLynch Jun 27 '12 at 13:57

2 Answers2

4

The answer here is to use lock:true.

School.findByName(name, [lock: true])
RyanLynch
  • 2,987
  • 3
  • 35
  • 48
1

Try with:

User.withTransaction {
    ...
    user.save(flush:true)
    sessionFactory.currentSession.flush()
    sessionFactory.currentSession.clear()
}
moskiteau
  • 1,104
  • 11
  • 19