David W. Van Couvering wrote:
Hi, Kristian, thanks for your research on this! I didn't know there
was more to be said on what SQL States should be used when. It's a
little daunting -- every time I change a SQL State in the client I have
to peruse this massive tome.
Anyway, I would probably use 25001, which is currently not in use. And
IMHO we should fix the embedded client to use this more descriptive
message.
I suppose I should fix this since it was my changes that introduced the
regression.
Thanks for taking care of it David :)
Fixing the test itself should be easy-going. I'll have a look at the
patch when it is ready.
--
Kristian
David
Kristian Waagan wrote:
David W. Van Couvering wrote:
Thanks for catching this, Kristian. As I go through messages on the
client, I try to find a matching message that already exists for the
embedded code. I have not tried to actually look at the "same" code
on the embedded side, as it's really hard to tell what the "same"
code is, and where it is.
I think the message "Invalid transaction state" is very vague, and in
this way is very general and reusable. I have heard Dan state that
general and reusable is better than specific and not reusable. I am
personally having trouble knowing how to best balance a
comprehensible message with one that is too specific.
In this case, however, I think "Invalid transaction state" is so
vague as to be pretty much unhelpful. I would vote that we migrate
CANNOT_CLOSE_ACTIVE_XA_CONNECTION from a client-specific message in
client/.../loc/clientmessages_en.properties to a reusable message in
engine/.../loc/messages_en.properties.
I also think that the standard SQL State of 25000 is incorrectly
used, here. This isn't an invalid transaction state. It's an
attempt to close a connection with an open transaction. If anything
it *might* be a connection exception (08000), but I actually think it
doesn't apply to either of these, and probably the SQL State, once
you migrate it, should start with "XJ" - JDBC exceptions.
I'm a bit confused. The SQL spec (2003) seem to think that closing a
connection with an active transaction is to be considered an invalid
transaction state.
INVALID_TRANSACTION_STATE_NO_SUBCLASS = "25000".
INVALID_TRANSACTION_STATE_ACTIVE_SQL_TRANSACTION = "25001".
There are more subclasses (see for instance p 776 of the second volume).
Also, under "17.3 <disconnect statement>", general rule 6:
"6) If any SQL-connection in L is active, then an exception condition
is raised: invalid transaction state —
active SQL-transaction."
(L is a list of SQL-connections - see general rule 5)
Sorry for not bringing this up earlier, but I've been sick and the
required karma to consult the SQL standard was not restored until today.
JDBC does not have much to say on the issue, from Connection.close():
"It is strongly recommended that an application explicitly commits or
rolls back an active transaction prior to calling the close method. If
the close method is called and there is an active transaction, the
results are implementation-defined."
The reason I react on the currently proposed solution, is the use of
an XA related SQLState. Can anyone explain to me why we want use that
when calling close on a "normal" SQL connection with an uncommitted
transaction on it?
And is the SQL standard (2003) the authoritative source on this issue?
I do agree with David that the generic "invalid transaction state" is
a bit vague, but since we have several subclasses (including one for
this specific case), we can elaborate on it if that is the correct way
to go.
thanks,
--
Kristian
I am also realizing that we as a community need to decide if we want
to ensure that the network client and the engine should always have
the same SQL States for the same exceptions. It's laudable, and if
we catch differences I think we should fix them, but I am not sure if
it should be *required*, especially for existing code. It is *very*
hard to reliably backport this consistency into existing code, as the
code paths on the two drivers are quite different. If anyone has any
ideas about this, it would be much appreciated.
David
P.S. I'll start running the jdbc40 test suite as well as derbyall
prior to checkin of i18n changes.
Kristian Waagan (JIRA) wrote:
[
http://issues.apache.org/jira/browse/DERBY-1149?page=comments#action_12371754
]
Kristian Waagan commented on DERBY-1149:
----------------------------------------
I need a little help on my issue. The following diff is from r388309:
---
/db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
2006/03/24 00:54:27 388308
+++
db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
2006/03/24 00:55:44 388309
[snip]
// The following precondition matches CLI semantics, see
SQLDisconnect()
if (!autoCommit_ && inUnitOfWork_ && !allowCloseInUOW_()) {
throw new SqlException(agent_.logWriter_,
- "java.sql.Connection.close() requested while a
transaction is in progress on the connection." +
- "The transaction remains active, and the
connection cannot be closed.");
+ new MessageId
(SQLState.CANNOT_CLOSE_ACTIVE_XA_CONNECTION));
}
[snip]
Is this change correct?
In my test, the SQLState used on the embedded side is
LANG_INVALID_TRANSACTION_STATE (25000):
# Transaction states, matches DB2
25000=Invalid transaction state.
The way I see it, without much knowledge about this, there are multiple
possible outcomes:
1) The change is invalid, and we start using
SQLSTATE.LANG_INVALID_TRANSACTION_STATE on the client as well.
2) The change is correct, and I change the test to reflect this.
3) The change is invalid, and we make
SQLSTATE.LANG_INVALID_TRANSACTION_STATE
more verbose (aka the old message on the client) and start using it
on the
client and update the message text for embedded.
What do you say?
'jdbc40/StatementTest.junit' fails under DerbyNetClient
-------------------------------------------------------
Key: DERBY-1149
URL: http://issues.apache.org/jira/browse/DERBY-1149
Project: Derby
Type: Test
Components: Regression Test Failure, Test
Versions: 10.2.0.0
Environment: JDK 1.6 (b76 used, believed to apply to all)
Reporter: Kristian Waagan
Assignee: Kristian Waagan
One of the tests in jdbc40/StatementTest.junit fails with the
following message:
"Attempt to shutdown framework: DerbyNetClient
0 add
....F.
There was 1 failure:
1)
testIsClosedWhenClosingConnectionInInvalidState(org.apache.derbyTesting.functionTests.tests.jdbc4.StatementTest)junit.framework.ComparisonFailure:
Unexpected exception thrown: Cannot close a connection while a
global transaction is still active.
expected:<java.sql.Connection.close() requested while a
transaction is in progress on the connection.The transaction
remains active, and the connection cannot be closed...> but
was:<Cannot close a connection while a global transaction is still
active...>
FAILURES!!!
Tests run: 5, Failures: 1, Errors: 0
Test Failed.
*** End: StatementTest jdk1.6.0-beta2 DerbyNetClient 2006-03-24
12:53:22 ***"
The reason is that the exception message text has been changed.
This comparison is only done when running DerbyNetClient, because
SQLState was not implemented there.
The checkin that caused the error:
"Author: davidvc
Date: Thu Mar 23 16:55:44 2006
New Revision: 388309
URL: http://svn.apache.org/viewcvs?rev=388309&view=rev
Log:
DERBY-839 (Partial). Internationalize Connection.java. Also upgraded
the "i18n lint" test to be a little more intelligent, and to not exit
on the first failure.
Passes derbynetclientmats. All changes are client-specific so
derbyall
was not run."
A