4

I'm using a vendor API to obtain a JDBC connection to the application's database. The API works when running in the application server or when running in a stand-alone mode. I want to run a series of SQL statements in a single transaction. I'm fine with them occurring in the context of the JTA transaction if it exists. However, if it doesn't then I need to use the JDBC transaction demarcation methods. (Calling these methods on a JDBC connection that is participating in a JTA transaction causes a SQLException.)

So I need to be able to determine whether the Connection came from the JTA enabled DataSource or if it's just a straight JDBC connection.

Is there a straight forward way to make this determination?

Thanks!

4

3 回答 3

4

Even if it's straight JDBC, you can have a JTA transaction enabled. Checking the autoCommit flag will NOT help in this regard. You can be in a transaction, distributed or otherwise, with autoCommit set to false. autoCommit set to true would tell you you're not in a distributed transaction but a value of false just means you won't auto-commit... it could be in any kind of transaction.

I think you're going to have to call UserTransaction.getStatus() and verify that it is not equal to Status.NoTransaction(). This would tell you if you're in a JTA transaction.

于 2008-10-12T11:03:16.367 回答
0

What thilo says does make sense.

Otherwise, Not sure of a straight way BUT I will give you a "hack" way

write a BAD SQL which you know will give a DB exception. That will result in a stack trace. From the stack trace, you can find out if it is a JTA derived connection or NOT ?

于 2008-10-07T22:47:09.003 回答
-1

You could try to check the Connection's autoCommit flag to see if it is in a transaction (regardless of where it came from). (Apparently, see the accepted answer, this does not work too well. I am not deleting this answer because the following still stands: )

But I think you should really modify your API to depend on external transactions exclusively. If you still want to support plain JDBC, wrap it into a separate API that just starts the transaction.

Update: Just re-read your question and saw that you are not providing an API, but want to use a container-managed connection. But still, can you just mandate (as part of your application's requirements) that JTA be in effect? If not, you could provide a configuration option to fall back to manually managed transactions. For such a critical feature it seems reasonable to require the proper configuration (as opposed to try to guess what would be appropriate).

于 2008-10-07T22:45:24.607 回答