02.06.2018 19:54, Mark Rotteveel wrote:
On 2-6-2018 17:56, Vlad Khorsun via Firebird-devel wrote:
02.06.2018 18:07, Mark Rotteveel wrote:
I just saw the following commit: 
https://github.com/FirebirdSQL/firebird/commit/bbf8348817c4592999fc137b18ba1be7326ad42d

This disallows execution of ALTER SESSION RESET if there are transactions 
active. I think this is too restrictive.

   Only from client POV and only at first look. Think about at as replacement
of detach\attach calls. At detach you have no active transactions or it will
fail with error.

For example, in Jaybird queries executed through the JDBC API will always be executed in a transaction. With this change, this statement must be executed without transaction, which means I must either include explicit support to detect this statement, or people need to break out of the JDBC API and use the underlying API, both are options I want to avoid (especially the last one). I think the same applies for other drivers.

   Could you add new method to reset connection ?
Will it "break out of the JDBC API" ?

That method would not be part of the JDBC API, so it would not be easily accessible. Technically, JDBC 4.3 introduced a feature where I could execute a session reset, but the rules for that specific API limits its usefulness and flexibility compared to being able to execute it like a normal statement.

And it would be hard to use for users in earlier Java versions (or people using older Jaybird versions) to use ALTER SESSION RESET without breaking out of the JDBC API to the Firebird-extensions to that API or even to the underlying internal API.

And it would make it harder to use this with external libraries like connection pool libraries (which allow init on checkout of the pool by executing a statement).

   BTW, does JDBC API requires that any statement shoud run within explicit
transaction ? Does Jaybird allow to not start implicit transaction with
statement ? Does Jaybirs support execution of "SET TRANSACTION" statement ?
Also, all new session management statements could run with no transaction
context.

JDBC API requires that statements are executed in a transaction. In theory I can break that rule, but the problem with that is that it requires explicit handling, which is 1) annoying to do and 2) brittle given the other API requirements involving transactions; and given my current health issues I don't see myself implementing that anytime soon.

And no, Jaybird has no specific handling for SET TRANSACTION, because the JDBC API specifies that users should use the methods defined in the API for things like transaction configuration, etc.

  All above is a good explanation why generic\universal API is bad :)

  BTW, looks like implicit transaction start (not supported by Firebird)
could solve this issues, agree ?

_"all new session management statements could run with no transaction context."_

There is a big difference between _could_ and _must_.

For flexibility sake, especially in the light of drivers whose API makes it harder to execute transaction-less (Jaybird and Firebird ADO.net, but AFAIK also FDB/pyfirebirdsql, possibly others), Firebird should allow execution of these statements in a transaction.

  Don't you think that 3 API calls where just one is enough not looks perfect ?

  Well, i understand your point and will not argue against it (while nor like it
nor agree with it).
Consider returning a warning if execution of ALTER SESSION RESET occurs within a transaction. If you must restrict it to only a single active transaction that's fine.

  Such warning is useless. Users will never read it. Engine not benefit from it 
too.

I could even live with a rule that this must be the first statement of a transaction (maybe even with requiring it to be the only statement of a transaction).

  What do you think if engine will internally rollback immediately before reset
and start new transaction (with the same properties as old one) after reset ?
Transaction handles will not be changed. I.e. for end user it looks like 
rollback
retaining but not retains old context.

Instead I propose that execution of ALTER SESSION RESET within a transaction will not fail if the current transaction is the only active transaction of the connection.

   It must check too much things to not break it by reset. And list of things
to check could be changed in the future.

And I think that restricting ALTER SESSION RESET to only transaction-less execution will make it hard to use, and restricts its usefulness.

  I strongly not agree here but... see above

It's currently not even possible to execute it from ISQL. In ISQL you get the 
error

"""
Statement failed, SQLSTATE = 01002
Cannot reset user session with open transactions (2 active)
"""

  isql will be adjusted a bit later

As an aside, the sqlstate is 01002 is warning(!) "disconnect error" according to the SQL standard, I don't think that state is suitable here.

  This is exactly the same state that used for isc_open_trans error on detach.

I think class 25 (invalid transaction state), and then maybe sqlstate 25001 (active SQL-transaction) or something like that. Alternatively this could be classified as class 08 (connection exception). Better might be to define our own non-standard subcode (eg 25501 or 08501) (sub-codes starting with 5-9 or I-Z are implementation-defined).

  Here i have no preference and could accept any argumented solution.

Also, I'm not 100% sure, but it also looks like the current restriction also doesn't allow for prepared but not yet committed transactions. Prepared transactions are not active, and presence of these should not block execution of ALTER SESSION RESET.

   If you speak about 2PC tranaction in prepared state - it is really active
and must be committed or rolled back (as any other active transaction).
If it in limbo state - it is inactive already.

Why does it matter for ALTER SESSION RESET? A prepared transaction should already by durable, I don't see how resetting the session has an impact on that transaction (or vice versa), so I don't think presence of prepared transactions should block.

  Ok, i agree - we should ignore prepared transactions.

BTW: I thought that limbo was the state of a prepared transaction.

  Engine doesn't release transaction lock on prepare, so, technically
it is alive until commit\rollback.

Regards,
Vlad

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to