-
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.
Transaction type: 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 VTQ.
Return TRANS_TYPE by TRX_ID from VTQ.
Return true if TX1 sees TX0 and TX1 != TX0.
create function TRX_SEES(TRX_ID1 bigint unsigned, TRX_ID0 bigint unsigned)
returns bool
begin
declare COMMIT_ID1 bigint unsigned default VTQ_COMMIT_ID(TRX_ID1);
declare COMMIT_ID0 bigint unsigned default VTQ_COMMIT_ID(TRX_ID0);
declare TRANS_TYPE1 enum('RR', 'RC') default VTQ_TRANS_TYPE(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 TRANS_TYPE1 = 'RC' then
return true;
end if;
# All other cases: TX1 does not see TX0
return false;
end
Return true if TX1 sees TX0 or TX1 == TX0.
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 transaction 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, max(COMMIT_ID) from VTQ where COMMIT_TS <= TS0 into (TRX_ID0, COMMIT_ID0);
COMMIT_ID0 is not used directly in these algorithms (since can be acquired by TRX_ID0), though it is used in implementation as optimization of TRX_SEES() function.
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 anyway.
-
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 transaction 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 transaction 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, min(COMMIT_ID) from VTQ where COMMIT_TS >= TS0 into (TRX_ID0, COMMIT_ID0);
-
Get TRX_ID1 corresponding to latest commit not later than TS1:
select TRX_ID, max(COMMIT_ID) from VTQ where COMMIT_TS <= TS1 into (TRX_ID1, COMMIT_ID1);
-
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.