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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.