-->
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.  [ 9 posts ] 
Author Message
 Post subject: session.flush doesn't commit
PostPosted: Tue Oct 18, 2005 5:26 pm 
Newbie

Joined: Tue Jan 11, 2005 2:26 pm
Posts: 15
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:

3.0.5 on Websphere 5.1.2

Name and version of the database you are using:

Oracle 9i

Hi,

I'm running an app on Websphere 5.1.2 using Hibernate version 3.0.5.

I'm using an MDB with JTA. Things are going well, except that when I try to manually commit some changes within a transaction, those changes are not committed until the end of the transaction.

I'm using session.flush().

My code is similar to the following:

public void doMethod() {
Session session = HibernateUtil.currentJTASession();
// pass through to sessionFactory.getCurrentSession();

// do queries

// do inserts and updates

session.flush();

// do more stuff

}

The transaction is managed by the container.

my hibernate.properties file is as follows:

# Hibernate TransactionFactory
# 1. delegates to JTA (if an existing transaction is underway the Session performs its
# work in that context, otherwise a new transaction is started)
hibernate.transaction.factory_class = org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.flush_before_completion true
hibernate.transaction.auto_close_session true
jta.UserTransaction=jta/usertransaction
#jta.UserTransaction=java:comp/UserTransaction

# Hibernate Transaction Manager Lookup Class
hibernate.transaction.manager_lookup_class = org.hibernate.transaction.WebSphereTransactionManagerLookup
#hibernate.transaction.manager_lookup_class = org.hibernate.transaction.WebSphereExtendedJTATransactionLookup


Any help would be appreciated.
-Ben


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 18, 2005 8:19 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
flush() is totally not the same thing as commit(). flush() just makes Hibernate push any pending changes to the database via JDBC. It does NOT have anything to do with when those changes get committed.

In a JTA environment, it's the container that manages the transaction for you. It would be very wrong for you to do a commit at all -- that's what JTA is *for*! The commit will happen once your MDB call completes (at least I'm pretty sure that's how it behaves with MDB's).

Why do you think you need to commit earlier than JTA would ordinarily? And you say "...when I try to manually commit some changes within a transaction..." -- that is very confused. You can't "commit within a transaction" -- if you commit, you're ending your transaction!

Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 3:24 pm 
Beginner
Beginner

Joined: Tue Oct 18, 2005 3:57 pm
Posts: 48
Location: Los Angeles, CA
RobJellinghaus wrote:
In a JTA environment, it's the container that manages the transaction for you.


What if you're running a standalone app and not a J2EE app? There's no CMT and you must use a Hibernate transaction? Because I've tried the same thing in a standalone Java app and had the same problem.

jd


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 3:52 pm 
Newbie

Joined: Tue Jan 11, 2005 2:26 pm
Posts: 15
Thanks Rob.

In the onMessage method of my MDB, I'm trying to create a persistent editlock row.

This row is supposed to tell other parts of the application that the object is locked.

The row doesn't get committed until the end of the transaction, however.

I guess this would be ok, since the row will get commited once the transaction commits and before the other updates and inserts to the table.

Is there another design?

the MDB fires (with a transaction) to receive the message. How do I create a lock row in another seperate transaction?

-Ben


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 4:19 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Locks, by definition, are only held until a transaction commits.

You want to do something like this:

session.refresh(yourLockObject, LockMode.UPGRADE);

at the top of your MDB.

Hibernate will then do a SELECT ... FOR UPGRADE (on databases that support this, including Oracle and Postgres), and that row will then be locked for the duration of the transaction that you refreshed in.

Locks are intended to prevent transactions that are both in progress -- i.e. both uncommitted -- from interfering.

Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 4:23 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Ah whoops, I misread your use case.

So this "edit-lock" row is basically supposed to get updated quickly by the MDB, and then committed so that the rest of the system knows who is the editor?

You will probably want to do the session.refresh technique, since you actually have a race condition if you don't. What if you update that row in one transaction, but meanwhile, another transaction tries to update the row with a different user? (i.e. what if two users try to grab the edit lock row at the same time?) You will want to make sure that those two transactions don't deadlock in any way. So you will probably want to deliberately lock the edit-lock row at the very start of your MDB, to get better control over how two concurrent lock attempts will be handled by the database.

Perhaps you only have one MDB that does this locking, so you're serializing lock attempts that way. That would also probably make sense. If that's the case, then it doesn't matter, because there will only ever be one transaction (from the singleton MDB) updating that edit-lock row.

Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 4:34 pm 
Newbie

Joined: Tue Jan 11, 2005 2:26 pm
Posts: 15
Hi Rob,

Unfortunately, I'm trying to creaet a new row to let the world know that this object is locked.

The problem then is that the new row doesn't appear until the commit phase of my transaction.

Can you offer a suggestion for that scenario?

Thanks,
-Ben


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 4:44 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Who else might be looking for that new row? What are the possible race conditions here? Is there only one MDB creating such rows, or are there many?

Why are you creating a new row rather than updating an existing row? How does the code elsewhere know what to look for?

And finally, if I'm being at all helpful, could you rate my answers accordingly? ;-)

Cheers!
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 4:59 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
jd001982 wrote:
RobJellinghaus wrote:
In a JTA environment, it's the container that manages the transaction for you.

What if you're running a standalone app and not a J2EE app? There's no CMT and you must use a Hibernate transaction? Because I've tried the same thing in a standalone Java app and had the same problem.

Yep, it's up to you in that case, but the behavior is the same: flush writes pending changes to JDBC, and that will make the database lock any rows you are writing to, but other transactions never see those writes until you commit. (Other transactions may hang waiting for the locks, but they won't see the writes.)

Cheers!
Rob


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.