Class TransactionalBuffer
- java.lang.Object
-
- io.debezium.connector.oracle.logminer.TransactionalBuffer
-
- All Implemented Interfaces:
AutoCloseable
@NotThreadSafe public final class TransactionalBuffer extends Object implements AutoCloseable
Buffer that stores transactions and related callbacks that will be executed when a transaction commits or discarded when a transaction has been rolled back.- Author:
- Andrey Pustovetov
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classTransactionalBuffer.DmlEventRepresents a DML event for a given table row.private static classTransactionalBuffer.LobEraseEventRepresents a LOB_ERASE eventprivate static classTransactionalBuffer.LobWriteEventRepresents a LOB_WRITE eventprivate static classTransactionalBuffer.LogMinerEventBase class for all possible LogMiner eventsprivate static classTransactionalBuffer.RecentlyCommittedTransactionRepresents a transaction boundary that was recently committed.private static classTransactionalBuffer.SelectLobLocatorEventRepresents a SELECT_LOB_LOCATOR eventprivate static classTransactionalBuffer.TransactionRepresents a logical database transaction
-
Field Summary
Fields Modifier and Type Field Description private Set<String>abandonedTransactionIdsprivate Clockclockprivate ErrorHandlererrorHandlerprivate ScnlastCommittedScnprivate static org.slf4j.LoggerLOGGERprivate ScnmaxCommittedScnprivate Set<TransactionalBuffer.RecentlyCommittedTransaction>recentlyCommittedTransactionIdsprivate Set<String>rolledBackTransactionIdsprivate OracleDatabaseSchemaschemaprivate OracleStreamingChangeEventSourceMetricsstreamingMetricsprivate Map<String,TransactionalBuffer.Transaction>transactions
-
Constructor Summary
Constructors Constructor Description TransactionalBuffer(OracleDatabaseSchema schema, Clock clock, ErrorHandler errorHandler, OracleStreamingChangeEventSourceMetrics streamingMetrics)Constructor to create a new instance.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) voidabandonLongTransactions(Scn thresholdScn, OracleOffsetContext offsetContext)If for some reason the connector got restarted, the offset will point to the beginning of the oldest captured transaction.private ScncalculateSmallestScn()voidclose()(package private) booleancommit(String transactionId, Scn scn, OracleOffsetContext offsetContext, Timestamp timestamp, ChangeEventSource.ChangeEventSourceContext context, String debugMessage, EventDispatcher<TableId> dispatcher)Commits a transaction by looking up the transaction in the buffer and if exists, all registered callbacks will be executed in chronological order, emitting events for each followed by a transaction commit event.(package private) Set<String>getRolledBackTransactionIds()(package private) booleanisEmpty()Returnstrueif buffer is empty, otherwisefalse.private booleanisForSameTableOrScn(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Checks whether the two events are for the same table or participate in the same system change.private booleanisSameTableRow(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Checks whether the two events are for the same table row.(package private) booleanisTransactionRegistered(String txId)private voidmergeNewColumns(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Merge column values fromeventwithprevEvent.private StringparseLobWriteSql(String sql)Parses aLOB_WRITEoperation SQL fragment.private List<String>readAndCombineLobWriteEvents(TransactionalBuffer.Transaction transaction, int index, boolean binaryData)Reads the transaction event queue and combines all LOB_WRITE events starting at the provided index.private intreadAndConsumeLobEraseEvents(TransactionalBuffer.Transaction transaction, int index)Read and remove all LobErase events detected in the transaction event queue.private voidreconcileTransaction(TransactionalBuffer.Transaction transaction)Reconcile the specified transaction by merging multiple events that should be emitted as a single logical event, such as changes made to LOB column types that involve multiple events.(package private) voidregisterDmlOperation(int operation, String transactionId, Scn scn, TableId tableId, LogMinerDmlEntry parseEntry, Instant changeTime, String rowId, Object rsId, long hash)Register a DML operation with the transaction buffer.private voidregisterEvent(String transactionId, Scn scn, long hash, Supplier<TransactionalBuffer.LogMinerEvent> supplier)Helper method to register a givenTransactionalBuffer.LogMinerEventimplementation with the buffer.(package private) voidregisterLobEraseOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId, long hash)Register aLOB_ERASEoperation with the transction buffer.(package private) voidregisterLobWriteOperation(int operation, String transactionId, Scn scn, TableId tableId, String data, Instant changeTime, String rowId, Object rsId, long hash)Register aLOB_WRITEoperation with the transaction buffer.(package private) voidregisterSelectLobOperation(int operation, String transactionId, Scn scn, TableId tableId, LogMinerDmlEntry parseEntry, String columnName, boolean binaryData, Instant changeTime, String rowId, Object rsId, long hash)Register aSEL_LOB_LOCATORoperation with the transaction buffer.(package private) voidregisterTransaction(String transactionId, Scn scn)Register a new transaction with the transaction buffer.(package private) booleanrollback(String transactionId, String debugMessage)Clears registered callbacks for given transaction identifier.private booleanshouldMergeDmlEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.DmlEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Attempts to merge the provided DML event with the previous event in the transaction.private booleanshouldMergeSelectLobLocatorEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.SelectLobLocatorEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Attempts to merge the provided SEL_LOB_LOCATOR event with the previous event in the transaction.StringtoString()(package private) voidundoDmlOperation(String transactionId, String undoRowId, TableId tableId)Undo a staged DML operation in the transaction buffer.(package private) ScnupdateOffsetContext(OracleOffsetContext offsetContext)Update the offset context based on the current state of the transaction buffer.
-
-
-
Field Detail
-
LOGGER
private static final org.slf4j.Logger LOGGER
-
transactions
private final Map<String,TransactionalBuffer.Transaction> transactions
-
schema
private final OracleDatabaseSchema schema
-
clock
private final Clock clock
-
errorHandler
private final ErrorHandler errorHandler
-
recentlyCommittedTransactionIds
private final Set<TransactionalBuffer.RecentlyCommittedTransaction> recentlyCommittedTransactionIds
-
streamingMetrics
private final OracleStreamingChangeEventSourceMetrics streamingMetrics
-
lastCommittedScn
private Scn lastCommittedScn
-
maxCommittedScn
private Scn maxCommittedScn
-
-
Constructor Detail
-
TransactionalBuffer
TransactionalBuffer(OracleDatabaseSchema schema, Clock clock, ErrorHandler errorHandler, OracleStreamingChangeEventSourceMetrics streamingMetrics)
Constructor to create a new instance.- Parameters:
schema- database schemaclock- system clockerrorHandler- the connector error handlerstreamingMetrics- the streaming metrics
-
-
Method Detail
-
getRolledBackTransactionIds
Set<String> getRolledBackTransactionIds()
- Returns:
- rolled back transactions
-
registerDmlOperation
void registerDmlOperation(int operation, String transactionId, Scn scn, TableId tableId, LogMinerDmlEntry parseEntry, Instant changeTime, String rowId, Object rsId, long hash)Register a DML operation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierparseEntry- parser entrychangeTime- time the DML operation occurredrowId- unique row identifierrsId- rollback sequence identifierhash- unique row hash
-
registerSelectLobOperation
void registerSelectLobOperation(int operation, String transactionId, Scn scn, TableId tableId, LogMinerDmlEntry parseEntry, String columnName, boolean binaryData, Instant changeTime, String rowId, Object rsId, long hash)Register aSEL_LOB_LOCATORoperation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierparseEntry- parser entrychangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifierhash- unique row hash
-
registerLobWriteOperation
void registerLobWriteOperation(int operation, String transactionId, Scn scn, TableId tableId, String data, Instant changeTime, String rowId, Object rsId, long hash)Register aLOB_WRITEoperation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierdata- data written by the LOB operationchangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifierhash- unique row hash
-
registerLobEraseOperation
void registerLobEraseOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId, long hash)Register aLOB_ERASEoperation with the transction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierchangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifierhash- unique row hash
-
undoDmlOperation
void undoDmlOperation(String transactionId, String undoRowId, TableId tableId)
Undo a staged DML operation in the transaction buffer.- Parameters:
transactionId- unique transaction identifierundoRowId- unique row identifier to be undonetableId- table identifier
-
registerTransaction
void registerTransaction(String transactionId, Scn scn)
Register a new transaction with the transaction buffer.- Parameters:
transactionId- unique transaction identifierscn- starting SCN of the transaction
-
commit
boolean commit(String transactionId, Scn scn, OracleOffsetContext offsetContext, Timestamp timestamp, ChangeEventSource.ChangeEventSourceContext context, String debugMessage, EventDispatcher<TableId> dispatcher)
Commits a transaction by looking up the transaction in the buffer and if exists, all registered callbacks will be executed in chronological order, emitting events for each followed by a transaction commit event.- Parameters:
transactionId- transaction identifierscn- SCN of the commit.offsetContext- Oracle offsettimestamp- commit timestampcontext- context to check that source is runningdebugMessage- messagedispatcher- event dispatcher- Returns:
- true if committed transaction is in the buffer, was not processed yet and processed now
-
updateOffsetContext
Scn updateOffsetContext(OracleOffsetContext offsetContext)
Update the offset context based on the current state of the transaction buffer.- Parameters:
offsetContext- offset context, should not benull- Returns:
- offset context SCN, never
null
-
rollback
boolean rollback(String transactionId, String debugMessage)
Clears registered callbacks for given transaction identifier.- Parameters:
transactionId- transaction iddebugMessage- message- Returns:
- true if the rollback is for a transaction in the buffer
-
abandonLongTransactions
void abandonLongTransactions(Scn thresholdScn, OracleOffsetContext offsetContext)
If for some reason the connector got restarted, the offset will point to the beginning of the oldest captured transaction. If that transaction was lasted for a long time, let say > 4 hours, the offset might be not accessible after restart, Hence we have to address these cases manually.In case of an abandonment, all DMLs/Commits/Rollbacks for this transaction will be ignored
- Parameters:
thresholdScn- the smallest SVN of any transaction to keep in the buffer. All others will be removed.offsetContext- the offset context
-
isTransactionRegistered
boolean isTransactionRegistered(String txId)
-
calculateSmallestScn
private Scn calculateSmallestScn()
-
isEmpty
boolean isEmpty()
Returnstrueif buffer is empty, otherwisefalse.- Returns:
trueif buffer is empty, otherwisefalse
-
close
public void close()
- Specified by:
closein interfaceAutoCloseable
-
registerEvent
private void registerEvent(String transactionId, Scn scn, long hash, Supplier<TransactionalBuffer.LogMinerEvent> supplier)
Helper method to register a givenTransactionalBuffer.LogMinerEventimplementation with the buffer.- Parameters:
transactionId- transaction id that contained the given eventscn- system change number for the eventsupplier- supplier function to generate the event if validity checks pass
-
parseLobWriteSql
private String parseLobWriteSql(String sql)
Parses aLOB_WRITEoperation SQL fragment.- Parameters:
sql- sql statement- Returns:
- the parsed statement
- Throws:
io.debezium.DebeziumException- if an unexpected SQL fragment is provided that cannot be parsed
-
reconcileTransaction
private void reconcileTransaction(TransactionalBuffer.Transaction transaction)
Reconcile the specified transaction by merging multiple events that should be emitted as a single logical event, such as changes made to LOB column types that involve multiple events.- Parameters:
transaction- transaction to be reconciled, nevernull
-
shouldMergeSelectLobLocatorEvent
private boolean shouldMergeSelectLobLocatorEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.SelectLobLocatorEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Attempts to merge the provided SEL_LOB_LOCATOR event with the previous event in the transaction.- Parameters:
transaction- transaction being processed, nevernullindex- event index being processedevent- event being processed, nevernullprevEvent- previous event in the transaction, can benull- Returns:
- true if the event is merged, false if the event was not merged.
-
shouldMergeDmlEvent
private boolean shouldMergeDmlEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.DmlEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Attempts to merge the provided DML event with the previous event in the transaction.- Parameters:
transaction- transaction being processed, nevernullindex- event index being processedevent- event being processed, nevernullprevEvent- previous event in the transaction, can benull- Returns:
- true if the event is merged, false if the event was not merged
-
readAndCombineLobWriteEvents
private List<String> readAndCombineLobWriteEvents(TransactionalBuffer.Transaction transaction, int index, boolean binaryData)
Reads the transaction event queue and combines all LOB_WRITE events starting at the provided index. for a SEL_LOB_LOCATOR event which is for binary data (BLOB) data types.- Parameters:
transaction- transaction being processed, nevernullindex- index to the first LOB_WRITE operation- Returns:
- list of string-based values for each LOB_WRITE operation
-
readAndConsumeLobEraseEvents
private int readAndConsumeLobEraseEvents(TransactionalBuffer.Transaction transaction, int index)
Read and remove all LobErase events detected in the transaction event queue.- Parameters:
transaction- transaction being processed, nevernullindex- index to the first LOB_ERASE operation- Returns:
- number of LOB_ERASE events consumed and removed from the event queue
-
isForSameTableOrScn
private boolean isForSameTableOrScn(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Checks whether the two events are for the same table or participate in the same system change.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent event that has been processed, may benull- Returns:
- true if the two events are for the same table or system change number, false otherwise
-
isSameTableRow
private boolean isSameTableRow(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Checks whether the two events are for the same table row.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent event that has been processed, nevernull- Returns:
- true if the two events are for the same table row, false otherwise
-
mergeNewColumns
private void mergeNewColumns(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Merge column values fromeventwithprevEvent.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent parent that has been processed, nevernull
-
-