So we built the system, and the whole time we were building it, it was always slow. Some of the lessons I learned about Oracle and database connections still leave my shaking my head. Anyway, we kept getting faster. And faster. But faster will still slow as dirt, quite honestly. I'd built a ton of apps that ran on other appservers, and they were always TONS faster than this. I was left scratching my head until I wore a bald spot in my hair. I mean, I'd tuned the code, and tuned it and tuned it. I was having halucinations of JProbe UIs, and it would not speed up.
So I was getting into quite a tight spot, as the customer was not able to actually USE the app, it was so slow. As it was more and more important that I actually fix the problem, I sat down one afternoon and read the "Container Managed Transactions" section of the weblogic docs yet again. And I noticed a weird footnote, that said something to the effect of "A transaction should use a single JDBC connection, as any connection that is used by the transaction, even if closed, remains associated with the transaction until it commits."
I sat straight up in my chair and grabbed the desk, as I thought I might faint.
The chase
Long story short: I was following the same pattern I (and probably lots of others) had always used, which is:
try { connection = dataSource.getConnection(); connection.executeXYZ(); } finally { connection.close(); }This would happen for each db operation I needed to do in the transaction, so what it turns out I was doing was using a HUGE swath of database connections (15-30 sometimes) for each transaction. Then, when I committed the outer TX, the Weblogic transaction manager would have to run a commit on each individual connection that was attached to the transaction. Which makes it yet slower. And the fact that those connections are unavailable to the server during the whole TX makes it yet slower still, as the connection pool was artificially exhausted by only a small number of users. The fix was to go from "connection per query" to "connection per transaction", which, if done the brute force way, is a massive code change (everywhere you currrently fetch a connection, you need to have it passed in). Turns out the fix was trivial if you do it using a vendor proprietary solution. In this case, proprietary saved my bacon.
The answer to my (and maybe your) ills is called the "Weblogic JTS Driver". You can read more about it here. What this does is change your API from using a DataSource to an old fashioned Driver, but it, under the hood, uses your connection pool and makes sure your single transaction always uses the same connection. Suddenly, my application went from crashing with 8 users, to handling a solid pounding by 60. And it was miller time.
Normally, I think most people would feel shunned and walk away rebuffed in some way because these other "super cool" programmers "won't email me back". I, on the other hand, think that these projects are basically shooting themselves in the foot, because I (and I suspect, many other talented programmers) are getting ignored when they try and contribute, and so they just basically go "aw, fuck it anyway" and never bother again because the team is too lazy or buried in their own hubris to respond to code submissions. I guess this is just a bit of a lament, and, if any open source project leaders are listening, a warning: ignore people who are trying to contribute at your own (and the rest of the industry's) peril. Open source lives and dies on the goodwill of the developers, and if you don't breed good will, you can't grow.
Other useful blogs I like to read:
misbehaving
boingboing
k5
/dev/null
crazy bob
igor's lampost
vanity foul
James Strachan's Radio Weblog
Otaku