-
Notifications
You must be signed in to change notification settings - Fork 5
Ordering of transactions
Transaction ID.
Commit ID assigned to transaction by second trx_sys_get_new_trx_id()
at commit phase. Pairs (TRX_ID, COMMIT_ID) form abstract time scale with begin, commit events strictly ordered.
Isolation level: RR for Repeatable Read, RC for Read Committed.
Timestamps for begin, commit events on physical time scale. Events are loosely ordered due to time measure inaccuracy (time jitter).
Return COMMIT_ID
by TRX_ID
from TRT.
Return ISO_LEVEL
by TRX_ID
from TRT.
Return true if TX1 sees TX0 and TRX_ID1 != TRX_ID0. Where TX1, TX0 transactions corresponding to TRX_ID1, TRX_ID0.
create function TRX_SEES(TRX_ID1 bigint unsigned, TRX_ID0 bigint unsigned)
returns bool
begin
declare COMMIT_ID1 bigint unsigned default TRT_COMMIT_ID(TRX_ID1);
declare COMMIT_ID0 bigint unsigned default TRT_COMMIT_ID(TRX_ID0);
declare ISO_LEVEL1 enum('RR', 'RC') default TRT_ISO_LEVEL(TRX_ID1);
# Trivial case: TX1 started after TX0 committed
if TRX_ID1 > COMMIT_ID0 then
return true;
end if;
# Concurrent transactions: TX1 committed after TX0 and TX1 is Read Committed
if COMMIT_ID1 > COMMIT_ID0 and ISO_LEVEL1 = 'RC' then
return true;
end if;
# All other cases: TX1 does not see TX0
return false;
end
Return true if TX1 sees TX0 or TRX_ID1 == TRX_ID0.
create function TRX_SEES_EQ(TRX_ID1 bigint unsigned, TRX_ID0 bigint unsigned)
returns bool
begin
# Trivial case: TX1 is TX0
if TRX_ID1 = TRX_ID0 then
return true;
end if;
# All other cases: call TRX_SEES()
return TRX_SEES(TRX_ID1, TRX_ID0);
end
select * from versioned for system_time as of transaction TRX_ID0;
Select records in queried table which modification was before or was TRX_ID0 and made defunct by transaction after TRX_ID0:
select *
from versioned
where
TRX_SEES_EQ(TRX_ID0, sys_trx_start) and TRX_SEES(sys_trx_end, TRX_ID0);
select * from versioned for system_time as of timestamp TS0;
-
Get TRX_ID0 corresponding to latest commit not later than TS0:
select TRX_ID, COMMIT_ID, max(COMMIT_TS) from TRT where COMMIT_TS <= TS0 into (TRX_ID0, COMMIT_ID0, COMMIT_TS0);
COMMIT_ID0 is not used directly in these algorithms (since it can be acquired by TRX_ID0), though it is used in implementation as optimization of
TRX_SEES()
function.If there are multiple TRT records at COMMIT_TS0, then select one corresponding to
max(COMMIT_ID)
.Note, that there is no need in time-jitter corrections as COMMIT_ID is protected from time-jitter effects. Transactions after TS0 affected by time-jitter will have COMMIT_ID lower than COMMIT_ID0 in any case.
-
Use transaction-based AS OF query:
select * from versioned for system_time as of transaction TRX_ID0;
select * from versioned for system_time from transaction TRX_ID0 to transaction TRX_ID1;
Select records in queried table which modification was before TRX_ID1 and made defunct by transaction after or by TRX_ID0:
select *
from versioned
where
TRX_SEES(TRX_ID1, sys_trx_start) and TRX_SEES_EQ(sys_trx_end, TRX_ID0);
select * from versioned for system_time between transaction TRX_ID0 and transaction TRX_ID1;
Select records in queried table which modification was before or was TRX_ID1 and made defunct by transaction after or by TRX_ID0:
select *
from versioned
where
TRX_SEES_EQ(TRX_ID1, sys_trx_start) and TRX_SEES_EQ(sys_trx_end, TRX_ID0);
select * from versioned for system_time from timestamp TS0 to timestamp TS1;
select * from versioned for system_time between timestamp TS0 and timestamp TS1;
-
Get TRX_ID0 corresponding to earliest commit not earlier than TS0:
select TRX_ID, COMMIT_ID, min(COMMIT_TS) from TRT where COMMIT_TS >= TS0 into (TRX_ID0, COMMIT_ID0, COMMIT_TS0);
If there are multiple TRT records at COMMIT_TS0, then select one corresponding to
min(COMMIT_ID)
. -
Get TRX_ID1 corresponding to latest commit not later than TS1:
select TRX_ID, COMMIT_ID, max(COMMIT_TS) from TRT where COMMIT_TS <= TS1 into (TRX_ID1, COMMIT_ID1, COMMIT_TS0);
If there are multiple TRT records at COMMIT_TS0, then select one corresponding to
max(COMMIT_ID)
. -
Use transaction-based FROM .. TO or BETWEEN .. AND query:
select * from versioned for system_time from transaction TRX_ID0 to transaction TRX_ID1; # or select * from versioned for system_time between transaction TRX_ID0 and transaction TRX_ID1;
- RR: Repeatable Read, transaction opens Read View at first read;
- RC: Read Committed, transaction opens Read View at each read.
- rrA started
- rrB started
- rrA or rrB finished
- rrB or rrA finished
- rcA started
- rcB started
- rcA finished
- rcB finished
- rcA started
- rcB started
- rcB finished
- rcA finished
- rrA started
- rcB started
- rcB finished
- rrA finished
- rrA started
- rcB started
- rrA finished
- rcB finished
- If two RR transactions run concurrently, order of them doesn't matter;
- If in two concurrent transactions RC finishes second, then it goes second.