Discussions

News: Correction to Reader Writer article and any feedback here...

  1. I've fallen victim to the DCL problem in the article so I'm posting a correction for the getLock snippet. The article was written some time ago before everybody knew DCL didn't work on SMP boxes. Plus, anyone with feedback is welcome to post on this thread.

    Here it is:

    ************

    import EDU.oswego.cs.dl.util.concurrent.*;

    public class MyLock {
      static ReadWriteLock myLock;
      public static synchronized ReadWriteLock getLock()
      {
        if(myLock == null)
        {
          myLock = new WriterPreferenceReadWriteLock();
        }
        return myLock;
      }
    }

    *************

    Thanks.
  2. Well, I guess that just because i did programming on this area, I'll add some comments.

    One small mistake:

    You don't provide for reentrant locks.
    This is bad because reentrant locks are very easy.

    Also this forces users of you ideas to break structured programming, by not allowing them to split coding into several methods, which is very often the case, at least I hit this wall myself, revised the architecture and use reentrant locking.

    The other thing that is at least very unclear is your "example" that basically says it doesn't work unless you have Oracle 8i advanced queueing, and in that case it doesn't discuss the implications on the transactional behaviour of the database.

    Not to mention that asynchronous notification of events is available only with OCI, so one could remain puzzled about your intentions of creating a self updatable cache in Java.

    Quite controversial example if good at all, don't you think ?


    If your article is about the utility of read/write locks then it is very good, but as to what regards the caching , it is very fuzzy.

    You might want to discuss it as a pattern, or keep it for yourself if you feel you found a gold nugget, but don't just sneak it as an example.


    Cheers,
    Costin
  3. Well, :-)

    First, what small mistake?, the reentrant problem, I suggest you read it again. I said if you want to do nested calls then use the reentrant lock classes from Dougs library instead of the ones I used initially. It's there in black and white, read it again.

    When I did this for real (I do actually work for a living, believe it or not) using Orbix and TopLink back in 1998 I used orb interceptors to handle the locking when the incoming corba request arrived and departed normally or via an exception so all the locking was actually transparent to the application code in any case. I would say this is the 'proper' thing to do for limited impact on 'structured' programming, i.e. make it invisible, it's just infrastructure or boiler plate code. You can do this today in J2EE servers that use an ORB so long as the ORB supports the standard OMG interceptor stuff. I wouldn't put it inline in the code when interceptors are available. You're just opening your self up for grief when someone forgets to get a lock or doesn't pair the acquire/release calls. The interceptor does it right every time.

    The intent of the article was, indeed, ReaderWriter locks not caching. Caching was discussed merely to show how ReaderWriter locks helped implement a distributed cache when using TopLink. I may provide a completed worked example in the future.

    I never said Oracle AQ was the only one that worked, I just said that the distributed caches may get refresh events from rolled back exceptions unless you use Oracle AQ as it's transactional. It still works, we'd just be flushing records from the cache unnecessarily when a transaction was rolledback.

    As for transactional issues in distributed caching thats a whole topic on to it-self.

    Your statement on asynchronous events require OCI is just false. Oracle AQ allows asynchronous events using either PL/SQL, OCI, and Java stored procedure using oracle AQ or JMS. The transaction gets commited, a message gets queued and then later at the consumers leisure, it can consume the message. It certainly sounds asynchronous to me. There are so many ways to skin a banana in Oracle now, I'd be wary of saying anything wasn't possible.

    BTW, what's the last comment supposed to mean? I could take that in a bad way indeed. What do you mean? The title of the article wasn't distributed caching, it was reader writer locking.
  4. Well, I was half kidding half seriously.

    Because the title of the article was suggesting more a transactional middleware (distributed) cache.
    Thing that as far as I know is unsolved both theoretically and practically, so therefore the suggestion with the gold nugget I should have said gold mine.

    Hope you didn't mind, but some readers without a certain level of expertise would read the article and live with the impression that is a normal thing to do, at least you should have put a warning "don't try at home" :)

    Especially you shouldn't mention at all about triggers that send non-transactional messages.

    In Oracle yes you can get messages from asynchronous queue as long as you poll for them.
    But I was saying that you cannot get asynchronous notication events unless you're using OCI.

    So yes you're right if you are talking about asynchronous messages, but you will not get yet asynchronous events (notification).

    Therefore the distributed cache is much harder to implement considering that in the J2EE platform for example you are not allowed to start a thread, so you cannot poll efficiently the messages generated by triggers you suggest.

    Anyway, the "data cache using readers and writers" is far beyond the scope of the article, and I would argue that is a little bit beyond the current state of technology.

    If you think otherwise, please share it with us, that's what I was suggesting.
    Of course such a knowledge would also be a gold mine, so it would be your right to keep it for yourself, but in that case it wouldn't be quite right to just drop a superficial paragraph on the subject.

    Cheers,
    Costin
  5. Nah,
    You're misquoting the article. The only reference to transactional was in terms of the cache refresh message being sent only when the modifying database transaction commits. I never said it was a 'transactional middleware cache'. You're reading more in to it than was there.

    Again, you're still mistaken on the polling Oracle comment. Any Oracle client can make a blocking call waiting for a message, check the docs if you haven't done this before. You can do this using OCI, PL/SQL or Java (AQ or JMS).

    I will get notification. My server just publishes the event on a JMS topic or I can just use Oracle AQ's native pub/sub APIs to do the same. Thats notification.

    As for whether a transactional cache is practical, take a look at how Oracle 8i Parallel Server works. I believe you will find a surprise. No, it's not perfect but Oracle basically maintains a transactional distributed block cache across the cluster on top of the database drives.

    Suppose we used an OR mapper inside Oracle 8i's VM. Disable the OR mapping caching facilities. The OR mapper will use Oracles internal JDBC driver which is colocated with the Oracle block cache. Oracle takes care of keeping its block cache current using its distributed lock manager. The OR mapper can therefore dispense with its cache as it is now colocated with Oracles cache.

    So, basically, we're leveraging Oracle 8iPS distributed caching to build what you say is beyond state of the art. We're running a Java based server application (available using Corba or EJB) colocated with a distributed transactional database cache (i.e. Oracles parallel block cache).

    You could use any Java OR mapper if you chose.

    It's not perfect but it's pretty good. To avoid the 'pinging' effect, we would need to use partitioned tables. Our application would send operations on a given data partition to a specific Oracle instance. This can help reduce pinging. If your data doesn't allow this partitioning then you live with pinging or switch to scaling vertically instead of horizontally. Pinging isn't as bad as it was pre 8i in any case and usually takes place now over a cluster interconnect (IBM SP switch, Suns backplane on a Ex000 box or on PCs over GigaNet cLan or Myrinet).

    Anyway, there it is, a future article will go in to this in more detail and show a couple of solutions with various trade offs. But, as usual, you pick your bed and then you sleep in it. Weigh your options go with the choice. It's just a question of knowing all the options and picking the appropriate one.
  6. Again, you're still mistaken on the polling Oracle comment.

    >Any Oracle client can make a blocking call waiting for a >message, check the docs if you haven't done this before. >You can do this using OCI, PL/SQL or Java (AQ or JMS).

    Exactly what I was saying. You have to make a blocking call, you don't get asynchronous notifications.
    The complications of using a blocking call to wait for cache update notifications are quite substantial and you didn't discuss that at all.

    Probably your soltuion may work for loose consistency data such as news feeds for example.

    It wouldn't work for data that needs to be transactionally consistent let's say price quotes for examples.

    Ok, you have a point with Oracle having some solutions, but it's basically reserved for Oracle 9i.
    As to deploying Corba or EJBs inside Oracle 8i, I believe that this solution hardly made it into production systems.

    But my basic point is :
     If the current state of the technology doesn't allow you to keep a transactionally consistent cache in the middleware, then why bother ?
     
     Can you or can you not keep transactional consistency with this cache, comparing let's say with the old client server approach ?

      If there are certain situations where you think a loose consistency model is good enough you should discuss that explicitly.


    I suppose I have to wait for your next article, where you'll bring more details.

    As to what Oracle is doing, yes if you put your middleware inside Oracle Database (I believ nobody has done that in production yet) you could get your notifications and everything right.
    But then what's the point in having another cache when the internal JDBC driver already accesses the internal cache ?

    Oracle claim to have solved the distributed consistent cache only with their upcoming Oracle 9i database and I believe it's only for their internal cache.
    I guess we'll have to wait and see.
     
    Cheers,
    Csotin.

      
  7. Hi,
    This thing about notifications not being asynchronous, what are you talking about :-) Start a thread in your app server at startup, the thread blocks waiting for a message from Oracle AQ and then updates the cache as previously mentioned using the locks. It's asynchronous. As for the EJB spec says no threads, gimme a break, the next guy that says that, tell them to get a real job doing real work.

    Price Quotes. It depends, real times prices is a notional concept at best. Every price a trader sees is 'old', a new one may be coming when he looks at the price. We try to reduce the latency between price generation and price display as much as possible thats all. We may even drop prices depending on the bandwidth between the price gateway and the broker and the frequency of price generation. A trader connected to a LAN gets everything, a trader connected using a 56K leased line may not be able to physically receive a high volume feed without backing up the prices, i.e. prices get pushed on faster than they get taken off and the prices start to go back in time.... So, we need to throttle the publication of prices on a subscriber by subscriber basis.

    Instinet uses distributed caching in an e-trading type environment, take a look for the compromises that they made for that, it's interesting (built with Tibco/RV, Persistence PowerTier EJB and Oracle 8iPS).

    Oracle has supported the parallel server since V7 (maybe before), the caching features added in V9 are related to client cached snapshots of the database that are queryable using SQL. That is pretty cool but you can do this also using products like TimesTen in front of the database.

    The comments related to if 'it's not perfect then why bother'. It all depends Cotzin, it totally depends on what you're trying to do, you can't just make statements like that, it really does depend. Maybe, we don't need it fully distributed and consistent. It may be acceptable to see old data so long as when we do updates, the updates are consistent. Look at Instinet for an example.

    Billy
  8. Ok,

    So it seems to me that we have some common ground.
    I wasn't trying to say that a non consistent cache is totally useless, maybe I put it wrongly.

    As you said, it depends, and in some situations it may be acceptable.
    Those situations need further analysis as to the degree of consistency/inconsistency you can achieve (like how old is data guranteed to be, if the cache can contain entries that no longer exists and so on).

    I don't doubt that you have the capacity to analyse these and provide custom solutions, however I was worried about the article treating it "easily" so you'd give the wrong impression to the uninitiated.

    I think it would have been beeter if you discussed a little bit what are the limitations and what are the implications of such a cache.

    As per what are Oracle mechanisms, I think we are talking about the same thing, only we view it differently :)
    I really don't know a thing about TopTen and probably is one of those many things I'll never have time to learn unless I bump into it :(
    But since you mentioned it, you made me curious.

    I'm not warry that threading is bad or forbidden by Sun, I'm more worried about an actual server.
    Although for now I can get away with java.io, some servers might actually enforce the threading restrictions some day.

    Costin.