Regarding pooled connections, unless I hear otherwise, I'll modify this to not get the id from the underlying physical connection but to have its own id instead, so that these are traceable independently.
I don't have any clarity on what I need to do to make this work with a diagnostics table, so I am not sure of any changes I need to make in that regard, any guidance anyone has will be much appreciated.
Comments please? If I don't here anything by say noon tomorrow I'll go ahead and implement the proposed changes.
Thanks,
David
David Van Couvering wrote:
Thanks for the quick reply, Dan, some responses below.
Daniel John Debrunner wrote:
David Van Couvering (JIRA) wrote:
[ http://issues.apache.org/jira/browse/DERBY-243?page=all ]
David Van Couvering updated DERBY-243: --------------------------------------
Attachment: DERBY-243.diff
I am attaching the patch that should resolve this bug. I added toString() to the
appropriate connection classes and updated the dataSourcePermissions.java and dataSourcePermissions_net.java tests to test toString(). I mostly just verify
that two connections do not have the same string and follow the expected pattern. I had to "sed" out the actual connection ids in the output so we
could guarantee a pass even if the ids change.
I'd like to see some crisper definition around what the return from toString() is meant to represent for a connection.
- with this implementation, two different application connections from the same PooledConnection end up with the same toString() output, because the toString() of the underlying connection is used.
I am still learning about PooledConnection, not having dealt with this before. I thought that PooledConnection was an interface only used by app servers and other containers implementing connection pools. This seems to match what I saw in my tests: regardless of what kind of access mechanism I used (DriverManager, DataSource, ConnectionPoolDataSource or XADataSource), I always ended up with an EmbedConnection30 or a NetConnection being returned to the application, and never a PooledConnection class.
It is true that multiple sessions in an app server using connection pooling will often get the same connection through the lifetime of the container VM. However, in terms of tracing a transaction, the connection id will be consistent for the lifetime of the transaction.
Do we need a toString() in PooledConnection for debugging a container's internal connection pool code? If so, I agree PooledConnection.toString() shouldn't refer to the underlying physical connection, and I can fix that...
- however, a connection returned by jdbc:default:connection, has a different toString() output to its parent connection.
That seems to be somewhat conflicting behaviour.
- do we want the class name in the output? I would say no.
Well, assuming that the user only ever sees a single type of connection class in a given VM (either NetConnection or EmbedConnection), then this would probably work, you would not get in the situation of having two connections with the same toString() output.
But, now you've got me thinking... If you have two systems running in different classloaders, you could still have non-unique ids. :(
I guess this could be solved if I follow Jack's original suggestion and used hashCode(), since this will be unique across all objects in a VM. But personally a simple integer id is a lot easier to read in a log file than a longer hex number, or an even longer decimal number... The connection id *could* be prepended with a system id, if such a thing exists.
However, thinking even further ahead, if we ever had a clustered system writing to a common log, even the Jack's identityHashCode solution would not be unique :) Which takes us back to a UUID. What do you think, should we worry about this or just worry about two systems in the same VM for now?
Another thing that would be very nice is if, in client/server mode, client connection toString() has a correlation to the resulting embedded connection toString() created on the server side for that session. This way you could get end-to-end correlation. I don't know if DRDA supports this; if people think this is a good idea I can investigate...
Sigh, and I thought this would be a simple fix, silly me! :)
I would like to see that at some point the return from toString() could be used to correlate the connection with information from a diagnostic table (vti). For example the value of PreparedStatement.toString() corresponds to the identifier column of the statement cache vti. This then could be used in diagnostics to show something like all locks for this connection.
Sorry, what's "vti"? This is a Derby acronym I have seen while browsing the source, I *think* it means "virtual table" but I'm not sure... Does such a diagnostic table exist? Where would I look to find one?
I looked at EmbedPreparedStatement. Its toString() invokes super.toString(). It's superclass is EmbedStatement, which has no toString() defined, and its superclass is ConnectionChild, which has no toString() defined. So you end up with <classname>@<hashCode>.
However, further digging reveals diag.StatementCache.java refers to GenericPreparedStatement.getObjectName(), which is a UUIDString.
At this point I must confess I am a bit lost. I can't find the relationship, BTW, between GenericPreparedStatement and EmbedPreparedStatement, and I can't figure out how diag.StatementCache is related to a VTI. Any guidance would be most appreciated.
I guess my key question for this bug fix would be: what would I need to do to ensure that the toString() from a connection can be used in a diagnostic table?
Thanks,
David
Dan.
