We've been doing some performance tuning with our WebSphere 3.5.6 application. We noticed that we had left all of our transactions as TX_REQUIRED. All of our external operations just read the datatabase with no updates, so we changed everything to TX_SUPPORTS (on our session and entity beans--we wrap entities with sessions).
The application is now much slower than before--by about a factor of 5. One operation that used to take about 8s now takes about a minute.
Is this a known issue with WebSphere, or somehow common to EJB in general? Is it because when running outside of a transaction, the container performs an ejbLoad for every getter (we're using CMP), while, when running in a transaction, there is only one ejbLoad for the duration of the transaction?
I'm pretty confused by this, so I would appreciate any help.
This could be due to a flaky JDBC driver. The driver not cleaning up DB resources correctly anymore, and it does do that correctly at the end of a transaction. How is the DB doing? Are you running out of cursors?
I've seen similar things with Oracle's JDBC drivers that come with 8.1.5 and 8.1.6. I've got good experiences with the JDBC driver from 8.1.7 using it against a 8.1.5 server.
Just my EUR 0.02
I don't think it's the JDBC driver, as the slow down is apparent after the first user operation after the server is started.
The answer is in your own post.
If you hit the same bean multiple times, without a transaction, then you'll get an ejbLoad for each call to the bean (plus an ejbStore() after each call (irrespective of whether you updated it.)
If you're within a transaction then you won't (since the theory goes that nothing else can update that object while you have it locked in the transaction.)
That would definitely make a huge difference.
If all your code does is read data then you should look into the read-only options on WebSphere. I've never used WS so I don't know what it has, but I'd be surprised if it can't do it. Usually you can set up your bean to be refreshed from the database every x seconds, but only if it's marked as read only. That way the server uses a totally different strategy as to when it calls ejbLoad etc.
WS probably also has an option to allow you to implement an isDirty() method which would let you stop it calling ejbStore(). But it will still call ejbLoad().
WARNING. The things I describe are NOT in the EJB spec. It's vendor specific.