-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Deadlock found when trying to get lock
PostPosted: Fri Oct 17, 2003 5:18 am 
Newbie

Joined: Fri Oct 17, 2003 5:09 am
Posts: 13
Location: Madrid, Espa
Hello,
I have a problem, the code is like this...

method1(...)
{
//Create Session
...
iter1 = session.find(...).iterator();
while (iter1.hasNext())
{
obj = iter1.next();
...
method2(session, obj);
...
session.save(obj);
}

method2 (session, obj)
{
Query q = session.createQuery(...);
q.setParameter("xxx", obj.getXXX());
q.setParameter("yyy", obj.getYYY());
q.list() // HERE throws the exception
}


GRAVE: Could not synchronize database state with session
java.sql.SQLException: General error, message from server: "Deadlock found when trying to get lock; Try restarting transaction"
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1628)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:886)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:945)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1809)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1602)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1488)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:478)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:454)
at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:20)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2100)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2061)
at net.sf.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1566)
at net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1372)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1332)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:76)
at msyslog.acciones.LastMessageRepeatedAccion.run(LastMessageRepeatedAccion.java:38)
at msyslog.Main.runAcciones(Main.java:392)
at msyslog.Main.main(Main.java:222)

thanks,
C


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 17, 2003 6:41 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Make sure to start your session's transaction, and to commit it after the save, as well as performing a flush() on the session after the save.

I see you're using a save() and not an update(), or saveOrUpdate().

After you've created obj from the iteration, do you make any changes to it before you get to the method2() call? Also, what is the query you perform in method2?

-G


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 17, 2003 7:22 am 
Newbie

Joined: Fri Oct 17, 2003 5:09 am
Posts: 13
Location: Madrid, Espa
Hello,
I have 2 bbdd:

Code in more detail:
main()
{
...
try{
...
// bbdd 1
sourceF = confSource.configure(confSourceFile).buildSessionFactory();
sessionSource = sessionsSource.openSession();
// bbdd2
destF = confDest.configure(confDestFile).buildSessionFactory();
sessionDest = sessionsDest.openSession();

// find in bbdd1
iter1 = sessionSource.find(...).iterator();
while (iter1.hasNext())
{
// Process obj to set attributes required in bbdd2
Syslog obj = (Syslog)iter1.next();
obj.setXXX(...);
...
method2(sessionDest, obj);
...
sessionDest.save(obj); // save in bbdd2
}
// Flush updates in bbdd1
sessionSource.flush();
sessionSource.connection().commit();
// Flush pending object inserts/updates in bbdd2
sessionDest.flush();
sessionDest.connection().commit();
...
}

method2 (sessionDest, obj)
{
...
Query q = session.createQuery(...);
q.setParameter("xxx", obj.getXXX());
q.setParameter("yyy", obj.getYYY());
q.list() // HERE throws the exception

iter1 = list.iterator();
while (iter1.hasNext())
{
// Process obj to set attributes required in bbdd2
Syslog obj = (Syslog)iter1.next();
obj.setXXX(...);
}
}

The exception always does not happen. the obj which I want to find and update in method2 can be of that I have processed (and saved in a previous iteration of main()) or that already was in bbdd2.

thanks,
C


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 17, 2003 7:46 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
cfgar wrote:

Code:
  while (iter1.hasNext())
  {
     // Process obj to set attributes required in bbdd2
     Syslog obj = (Syslog)iter1.next();
     obj.setXXX(...);


* This is where the problem seems to happens. You change the data and I believe Hibernate puts a lock on that record.

* I assume that you start the transaction for each session before you being using them?

* Something that is bugging me, and hopefully one of the Hibernate team can answer this, is: when you create an object that is linked to a specific sessionFactory, can you simply save() that object in a completely different sessionFactory?

Would it not be better to have some class that takes that object as a parameter, and returns a "copy" of it. e.g.

Code:
public static User copyUser (User user) {
    User result = new User();

    result.setPropertA(user.getPropertyA);
    ...
    //do this for non-ID properties, and call similar methods for all child objects

    return result;
}


I'm thinking it's the last thing - about the sessionFactory...

-G


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 17, 2003 8:38 am 
Newbie

Joined: Fri Oct 17, 2003 5:09 am
Posts: 13
Location: Madrid, Espa
Only it has failed once, but not identified the cause.
* I assume that you start the transaction for each session before you being using them?

Only use these 2 sessions, and only call sessionsFact.openSession() before find objects to process. start the transaction? it does not start hibernate?

and only flush and commit after processing (at end of main()).

The process:
Code:
// find in bbdd1
iter1 = sessionSource.find(...).iterator();
while (iter1.hasNext())
{
  // Process obj
  Syslog currentObj = (Syslog)iter1.next()
  process(currentObj); //set attributes

  findOtherObjectAndUpdateIt(sessionDest, currentObj);
  sessionDest.save(currentObj);
}

sessionDest.flush();
sessionDest.connection().commit();


the method2 findOtherObjectAndUpdateIt(sessionDest, obj) search another object in sessionDest (bbdd2):

Code:
findOtherObjectAndUpdateIt (sessionDest, currentObj)
{
...
Query q = session.createQuery(...);
q.setParameter("xxx", currentObj.getXXX());
q.setParameter("yyy", currentObj.getYYY());
list2 = q.list() // HERE throws the exception
iter2 = list2.iterator();
while (iter2.hasNext())
{
// Process otherObject to set attributes required in bbdd2
Syslog otherObject = (Syslog)iter2.next();
otherObject.setXXX(...);
}
}


the otherObject that i want to update can be of that I have processed in iter1 (a previous currentObj) or that already was in bbdd2 (not find in this iter1 bbdd1).

I don't know if the problem is transactions, or if the otherObject is one of previously process (found in bbdd1) and still has not been flush and commit or what?

Thanks again for all,
Cesar.

PD: You excuse my terrible english.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.