Issue Details (XML | Word | Printable)

Key: CORE-3525
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Vlad Khorsun
Reporter: Vlad Khorsun
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Autonomous transactions wrongly inherit run-time flags of "parent" transaction

Created: 16/Jun/11 07:27 AM   Updated: 18/Jan/16 05:08 PM
Component/s: Engine
Affects Version/s: 2.5.0
Fix Version/s: 2.5.1, 3.0 Alpha 1

QA Status: No test


 Description  « Hide
Currently autonomous transactions inherits characteristics of "parent" transaction (such as isolation level, read-only, wait mode).
Code that starts autonomous transaction just copied "parent" transaction's flags. This is wrong and at least inefficient.
Autonomous transaction should copy only flags which describes transaction characteristics, i.e. flags which could be set by transaction_options() function.

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Pavel Zotov added a comment - 20/Dec/15 03:15 PM
Can anyone explain me, what exactly flags should be inherited by ATX ?
In jrd/tra.cpp one may see that WAIT / lock_timeout, and also isol. level DO present in this function:
===
$ cat -n tra.cpp | tail --lines=+2616 | head -100
  2616 static void transaction_options(thread_db* tdbb,
  2617 jrd_tra* transaction,
  2618 const UCHAR* tpb, USHORT tpb_length)
  2619 {
. . .
  2630 SET_TDBB(tdbb);
  2631
  2632 if (!tpb_length)
  2633 return;
  2634
  2635 const UCHAR* const end = tpb + tpb_length;
  2636
  2637 if (*tpb != isc_tpb_version3 && *tpb != isc_tpb_version1)
  2638 ERR_post(Arg::Gds(isc_bad_tpb_form) <<
  2639 Arg::Gds(isc_wrotpbver));
  2640
  2641 RelationLockTypeMap lockmap;
  2642
  2643 TriState wait, lock_timeout; ------------------------------------------------------------- <<< ----------------
  2644 TriState isolation, read_only, rec_version;
  2645 bool anylock_write = false;
. . .
  2696 case isc_tpb_wait: ------------------------------------------------------------------ <<< ---------------
  2697 if (!wait.assignOnce(true))
  2698 {
  2699 if (!wait.asBool())
  2700 {
  2701 ERR_post(Arg::Gds(isc_bad_tpb_content) <<
  2702 Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_wait" ) <<
  2703 Arg::Str("isc_tpb_nowait"));
  2704 }
  2705 else
  2706 {
  2707 ERR_post(Arg::Gds(isc_bad_tpb_content) <<
  2708 Arg::Gds(isc_tpb_multiple_spec) << Arg::Str("isc_tpb_wait"));
  2709 }
  2710 }
  2711 break;
. . .
===

I haven't any understanding of this code (as C++ at all) but this ticket still hasn't appropriate .fbt in test repo.

Vlad Khorsun added a comment - 20/Dec/15 03:43 PM
> Can anyone explain me, what exactly flags should be inherited by ATX ?


From tra.h

// flags derived from TPB, see also transaction_options() at tra.cpp
const ULONG TRA_OPTIONS_MASK = (TRA_degree3 | TRA_readonly | TRA_ignore_limbo | TRA_read_committed |
TRA_autocommit | TRA_rec_version | TRA_no_auto_undo | TRA_restart_requests);

Pavel Zotov added a comment - 20/Dec/15 04:02 PM
SQL> select * from mon$transactions;
...
MON$ISOLATION_MODE 3 --- ==> TRA_degree3; TRA_read_committed; TRA_rec_version
MON$LOCK_TIMEOUT -1
MON$READ_ONLY 0 -- ==> TRA_readonly
MON$AUTO_COMMIT 0 -- ==> TRA_autocommit
MON$AUTO_UNDO 1 -- ==> TRA_no_auto_undo
MON$STAT_ID 15

Seems that mon$transactions can`t help in defining of TRA_ignore_limbo & TRA_restart_requests values.
Am I right ?

Vlad Khorsun added a comment - 20/Dec/15 04:15 PM
> Seems that mon$transactions can`t help in defining of TRA_ignore_limbo & TRA_restart_requests values.
Yes

The ticket was mostly about *not* copying flags that shouln't be copied.

Pavel Zotov added a comment - 20/Dec/15 04:44 PM
> The ticket was mostly about *not* copying flags that shouln't be copied.

That's mean that test should check only following flags:

382 const ULONG TRA_system = 0x1L; // system transaction
384 const ULONG TRA_reconnected = 0x4L; // reconnect in progress
388 const ULONG TRA_prepare2 = 0x40L; // transaction has updated RDB$TRANSACTIONS
390 const ULONG TRA_invalidated = 0x100L; // transaction invalidated by failed write
391 const ULONG TRA_deferred_meta = 0x200L; // deferred meta work posted
396 const ULONG TRA_restart_requests = 0x4000L; // restart all requests in attachment
398 const ULONG TRA_precommitted = 0x10000L; // transaction committed at startup
399 const ULONG TRA_own_interface = 0x20000L; // tra_interface was created for internal needs

But no any field in mon$transactions can be found for them - so, I'll try to find something in FB-Python doc ( e.g. in "Advanced Transaction Control").

It's interesting also that [NO] WAIT | LOCK_TIMEOUT parameter is not specified:
1) neither in mask:

(TRA_degree3 | TRA_readonly | TRA_ignore_limbo | TRA_read_committed |
TRA_autocommit | TRA_rec_version | TRA_no_auto_undo | TRA_restart_requests);

2) nor in enumeration "Flag definitions for tra_flags".

So what about current behaviour (implicit "wait"-inheritance in ATx) - is it wrong or no ?

Vlad Khorsun added a comment - 20/Dec/15 06:55 PM
a) You can't check flags that is not set using user API ( for ex.i.e. internal run-time flags).
b) Wait mode can't be set via SQL statement thus it is inherited. You can check if it is true or not. It is not stored in tx flags, btw