Subject Re: External procedures: implementation proposal.
Author Roman Rokytskyy
> Your code sequence:
>
> InitialContext ctx = new InitialContext();
> UserTransaction tx = ctx.lookup("UserTransaction");
>
>
> is a good example of a poor use of globals. The class
> InitialContext has no intrinsic context, and must grub around
> through globals or native functions to find things. It would be
> much better for the infrastructure to to pass the user transaction
> to your function than to expect to be able to pick it out of the
> ether. Even better would be to pass a full database context to your
> function, and in Java, the database context is an instance of the
> Connection interface.

No, that's a bit different example and comes from the fact that X/Open
Distributed Transaction Processing specification requires a
transaction-per-thread mapping. This is reflected in the J2EE
specification, where the calls go from one component to other in one
thread and share the same transaction context. In this case TLS is
natural here - there is no point to pass UserTransaction (or just
Transaction) instance with each call if that call is anyway executed
within the same transaction context. I have not check the EJB3 and
dependency injection yet, but David confirmed that there are some
places where TLS are unavoidable.

I won't argue that global variables are good thing, though I think I
will argue (or just shut up, but will still have this opinion) that
external procedure performs the job in the same thread it was called
in, it does not spawn threads and so on. Therefore, it is more or less
natural (at least for me) to associate the connection/callback with
the thread in which call is executed. Also, at least in FB 1.5, all
needed information was already stored in the TLS (if I remember
correctly that was TDBB structure, parts of which were for example
passed into the UDF together with parameter descriptor to provide a
possibility to access the BLOB fields, though I was reading FB sources
more than year ago, so some inconsistencies/errors might be present).

> To be completely frank, I don't like the practice of pulling context
> out of the ether. Every function, procedure, and method in the
> system should be passed the context necessary to perform its
> function. There are exceptions, like the threading package itself
> and the code that manages locales and system properties. Passing
> database context to a database procedure, however, should be
> explicit.

Ok, I have no problem with that. At the end that will be one more
parameter called "context" to the ExternalProcedure::open(...) method.
The "only" task left is to define how it looks like.

> A secondary advantage of passing explicit database context is that
> it allows a database procedure to executed in other contexts outside
> the database engine. You will probably discover that debugging Java
> running inside database engine is not always simple to debug. If
> you design your interfaces correctly, you should be able to run a
> database procedure faithfully in an external testbed.

For Java that is not so problematic, since one can easily emulate the
"jdbc:default:connection" in the external testbed. Though this might
be needed for other languages. Also, it is possible to debug the
JavaSP directly in the engine via remote debugging, so that is not an
issue.

Roman