private void commit(byte command, long txn, long txPin) throws JournalException { boolean force = command == Tx.TX_FORCE; Partition<T> partition = lastNonEmptyNonLag(); Partition<T> lag = getIrregularPartition(); tx.command = command; tx.txn = txn; tx.txPin = txPin; tx.prevTxAddress = txLog.getCurrentTxAddress(); tx.journalMaxRowID = partition == null ? -1 : Rows.toRowID(partition.getPartitionIndex(), partition.size()); tx.lastPartitionTimestamp = partition == null || partition.getInterval() == null ? 0 : partition.getInterval().getLo(); tx.lagSize = lag == null ? 0 : lag.open().size(); tx.lagName = lag == null ? null : lag.getName(); tx.symbolTableSizes = new int[getSymbolTableCount()]; tx.symbolTableIndexPointers = new long[tx.symbolTableSizes.length]; for (int i = 0; i < tx.symbolTableSizes.length; i++) { SymbolTable tab = getSymbolTable(i); tab.commit(); if (force) { tab.force(); } tx.symbolTableSizes[i] = tab.size(); tx.symbolTableIndexPointers[i] = tab.getIndexTxAddress(); } tx.indexPointers = new long[getMetadata().getColumnCount()]; for (int i = Math.max(txPartitionIndex, 0), sz = nonLagPartitionCount(); i < sz; i++) { Partition<T> p = getPartition(i, true); p.commit(); if (force) { p.force(); } } if (partition != null) { partition.getIndexPointers(tx.indexPointers); } tx.lagIndexPointers = new long[tx.indexPointers.length]; if (lag != null) { lag.commit(); if (force) { lag.force(); } lag.getIndexPointers(tx.lagIndexPointers); } txLog.write(tx, txn != -1); if (force) { txLog.force(); } }
private void rollback0(long address, boolean writeDiscard) throws JournalException { if (address == -1L) { notifyTxError(); throw new IncompatibleJournalException( "Server txn is not compatible with %s", this.getLocation()); } txLog.read(address, tx); if (tx.address == 0) { throw new JournalException("Invalid transaction address"); } if (writeDiscard) { LOGGER.info( "Journal %s is rolling back to transaction #%d, timestamp %s", metadata.getLocation(), tx.txn, Dates.toString(tx.timestamp)); writeDiscardFile(tx.journalMaxRowID); } // partitions need to be dealt with first to make sure new lag is assigned a correct // partitionIndex rollbackPartitions(tx); Partition<T> lag = getIrregularPartition(); if (tx.lagName != null && tx.lagName.length() > 0 && (lag == null || !tx.lagName.equals(lag.getName()))) { Partition<T> newLag = createTempPartition(tx.lagName); setIrregularPartition(newLag); newLag.applyTx(tx.lagSize, tx.lagIndexPointers); } else if (lag != null && tx.lagName == null) { removeIrregularPartitionInternal(); } else if (lag != null) { lag.truncate(tx.lagSize); } if (tx.symbolTableSizes.length == 0) { for (int i = 0, sz = getSymbolTableCount(); i < sz; i++) { getSymbolTable(i).truncate(); } } else { for (int i = 0, sz = getSymbolTableCount(); i < sz; i++) { getSymbolTable(i).truncate(tx.symbolTableSizes[i]); } } appendTimestampLo = -1; appendTimestampHi = -1; appendPartition = null; txLog.writeTxAddress(tx.address); txActive = false; }