RE: reference to the database
Leo Mekenkamp <[email protected]>
| Newsgroups | gmane.comp.java.ozone.user |
|---|---|
| Message-ID | <1079551427.5088.35.camel@jupiter> |
On Wed, 2004-03-17 at 11:16, Wong Liong Hung wrote: > > -----Original Message----- > > From: Leo Mekenkamp [mailto:[email protected]] > > Sent: Wednesday, March 17, 2004 4:49 PM > > To: Wong Liong Hung > > Subject: RE: [Ozone-users] reference to the database > > > > > > On Wed, 2004-03-17 at 09:38, Wong Liong Hung wrote: > > > I face problem when using the "setting the db object as a > > static member of a > > > class" approach with transaction. When calling > > > engine.setModel("BMW") within transaction (See the code below). > > I got the > > > following exception > > > > > > java.lang.IllegalStateException: Attempt to receive() without > > prior send(). > > > at EngineImpl_Proxy.setModel(Unknown Source) > > > at Client.main(Unknown Source) > > > > > > The setModel() method calls add() method of Store. StoreImpl is > > a singleton > > > class with the static getInstance() method for > > > creating StoreImpl object if it doesn't already exist and > > getting the one > > > and only instance of StoreImpl object from ozone. > > > Both setModel() and add() are ozone update methods. > > > > > > If I change the following statement > > > singleton = (Store)Client.db.objectForName("Store" ); > > > to > > > singleton = (Store)Env.currentEnv().database.objectForName("Store" ); > > > > > > The program works fine. However, if I call > > StoreImpl.getInstance() outside > > > of transaction block, I got the exception mentioned > > > in my previous message. > > > Exception in thread "main" java.lang.NullPointerException > > > at org.ozoneDB.Database.objectForName(Database.java:132) > > > at Client.main(Unknown Source) > > > > In your case using external transactions are complicating matters > > unnecessary. You are better of not using them. Ozone uses implicit > > transactions for you most of the time. > > Below is what I want to do:- > void doSomething() { > try { > transaction.begin > a = db.createObject > a.initialize() ---> a.value = 1 //called from a.initialize() > b = db.createObject //called from a.initialize() > b.initialize() //called from a.initialize() > a.update() > c = db.createObject > c.initialize() > > d.getInstance().add(a); //singleton object > e.getInstance().addName(a); //singleton object > transaction.commit() > } catch (Exception e) { > transaction.rollback() > } > } > > 1. doSomething() is a method of non-ozone object. Hence, I cannot depend on > implicit > transactions to control the commit and rollback of all of the method which I > call in doSomething, right? Right. But why not make doSomething a method in an ozone object? Since it is preferred to have all business logic in objects that are used on a client, that may be a better option. That business action either fails (rolls back) or completes successfully (commits). That's all a client shoud be concerned with. > 2. Without using external transaction, how can I rollback the change made to > the a object if c.initialize() failed? You cannot. But again, that logic should be 'encoded' in business objects, and business objects and ozone objects make a fine combination. > 3. If I depend on implicit transactions and by making a.initialize() as an > ozone update method, exception thrown in b.initialize() will cause the > a.value NOT being updated, right? public class FooImpl implements Foo extends OzoneObject { private int a; // ... public int getA() { return a; } public void setA(int a) { this.a = a; } public bar(Foo other) { a = 100; other.setA(200); throw new RuntimeException("always"); } } client side: Foo one; Foo two; //... one.setA(0); two.setA(1); System.out.println(one.getA()); System.out.println(two.getA()); try { one.bar(two); } catch (RuntimeException ignore) { System.out.println("exception"); } System.out.println(one.getA()); System.out.println(two.getA()); Output on the client will be: 0 1 exception 0 1 > > (...) > > > public static Store getInstance() throws Exception { > > > if(singleton == null) { > > > synchronized(Store.class) { > > > singleton = (Store)Client.db.objectForName("Store" ); > > > > What you are doing here in called double checked locking. Double checked > > locking is an anti-pattern (i.e. should NOT be used); it has serious > > repercussions if your program runs on a multiprocessor machine and even > > on a single cpu machine. > > What I'm trying to do is create a singleton class to make sure that only one > instance exist in any point of time and hide the use of ozone from the > caller. Any idea this can be achieved without using double checked locking. Please read http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html and/or http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html and/or http://www-106.ibm.com/developerworks/java/library/j-dcl.html. Cheers, Leo -- .--. .---------------.----------------------------------------. |o_o | | Leo Mekenkamp | Free, as in 'beer' and as in 'speech': | |:_/ | | +31 641234919 | office software http://openoffice.org | // \ \ | | 100% java odbms http://ozone-db.org | (| | ) | Long Live Tux | e-mail & browser http://mozilla.org | /'\_ _/`\ | | operating system http://linux.org | \___)=(___/ `---------------'----------------------------------------' ------------------------------------------------------- This SF.Net email is sponsored by: IBM Linux Tutorials Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click