Search in sources :

Example 26 with Transaction

use of herddb.model.Transaction in project herddb by diennea.

the class TableSpaceManager method executeStatementAsyncInternal.

private CompletableFuture<StatementExecutionResult> executeStatementAsyncInternal(Statement statement, StatementEvaluationContext context, TransactionContext transactionContext, boolean rollbackOnError) throws StatementExecutionException {
    Transaction transaction = transactions.get(transactionContext.transactionId);
    if (transaction != null && !transaction.tableSpace.equals(tableSpaceName)) {
        return Futures.exception(new StatementExecutionException("transaction " + transaction.transactionId + " is for tablespace " + transaction.tableSpace + ", not for " + tableSpaceName));
    }
    if (transactionContext.transactionId > 0 && transaction == null) {
        return Futures.exception(new StatementExecutionException("transaction " + transactionContext.transactionId + " not found on tablespace " + tableSpaceName));
    }
    boolean isTransactionCommand = statement instanceof CommitTransactionStatement || statement instanceof RollbackTransactionStatement || // AlterTable implictly commits the transaction
    statement instanceof AlterTableStatement;
    if (transaction != null) {
        transaction.touch();
        if (!isTransactionCommand) {
            transaction.increaseRefcount();
        }
    }
    CompletableFuture<StatementExecutionResult> res;
    try {
        if (statement instanceof TableAwareStatement) {
            res = executeTableAwareStatement(statement, transaction, context);
        } else if (statement instanceof SQLPlannedOperationStatement) {
            res = executePlannedOperationStatement(statement, transactionContext, context);
        } else if (statement instanceof BeginTransactionStatement) {
            if (transaction != null) {
                res = Futures.exception(new StatementExecutionException("transaction already started"));
            } else {
                res = beginTransactionAsync(context, true);
            }
        } else if (statement instanceof CommitTransactionStatement) {
            res = commitTransaction((CommitTransactionStatement) statement, context);
        } else if (statement instanceof RollbackTransactionStatement) {
            res = rollbackTransaction((RollbackTransactionStatement) statement, context);
        } else if (statement instanceof CreateTableStatement) {
            res = CompletableFuture.completedFuture(createTable((CreateTableStatement) statement, transaction, context));
        } else if (statement instanceof CreateIndexStatement) {
            res = CompletableFuture.completedFuture(createIndex((CreateIndexStatement) statement, transaction, context));
        } else if (statement instanceof DropTableStatement) {
            res = CompletableFuture.completedFuture(dropTable((DropTableStatement) statement, transaction, context));
        } else if (statement instanceof DropIndexStatement) {
            res = CompletableFuture.completedFuture(dropIndex((DropIndexStatement) statement, transaction, context));
        } else if (statement instanceof AlterTableStatement) {
            res = CompletableFuture.completedFuture(alterTable((AlterTableStatement) statement, transactionContext, context));
        } else {
            res = Futures.exception(new StatementExecutionException("unsupported statement " + statement).fillInStackTrace());
        }
    } catch (StatementExecutionException error) {
        res = Futures.exception(error);
    }
    if (transaction != null && !isTransactionCommand) {
        res = res.whenComplete((a, b) -> {
            transaction.decreaseRefCount();
        });
    }
    if (rollbackOnError) {
        long txId = transactionContext.transactionId;
        if (txId > 0) {
            res = res.whenComplete((xx, error) -> {
                if (error != null) {
                    LOGGER.log(Level.FINE, tableSpaceName + " force rollback of implicit transaction " + txId, error);
                    try {
                        rollbackTransaction(new RollbackTransactionStatement(tableSpaceName, txId), context).get();
                    } catch (InterruptedException ex) {
                        Thread.currentThread().interrupt();
                        error.addSuppressed(ex);
                    } catch (ExecutionException ex) {
                        error.addSuppressed(ex.getCause());
                    }
                    throw new HerdDBInternalException(error);
                }
            });
        }
    }
    return res;
}
Also used : HDBException(herddb.client.HDBException) SystablesTableManager(herddb.core.system.SystablesTableManager) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) TableCheckpoint(herddb.core.AbstractTableManager.TableCheckpoint) Table(herddb.model.Table) ClientConfiguration(herddb.client.ClientConfiguration) SyslogstatusManager(herddb.core.system.SyslogstatusManager) OpStatsLogger(org.apache.bookkeeper.stats.OpStatsLogger) IndexAlreadyExistsException(herddb.model.IndexAlreadyExistsException) Map(java.util.Map) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) LogNotAvailableException(herddb.log.LogNotAvailableException) PduCodec(herddb.proto.PduCodec) CommitLogResult(herddb.log.CommitLogResult) ClientSideMetadataProviderException(herddb.client.ClientSideMetadataProviderException) LogSequenceNumber(herddb.log.LogSequenceNumber) Set(java.util.Set) ScanStatement(herddb.model.commands.ScanStatement) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) HDBClient(herddb.client.HDBClient) TranslatedQuery(herddb.sql.TranslatedQuery) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) TableDataChecksum(herddb.data.consistency.TableDataChecksum) DropTableStatement(herddb.model.commands.DropTableStatement) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Bytes(herddb.utils.Bytes) SysdualTableManager(herddb.core.system.SysdualTableManager) LogEntry(herddb.log.LogEntry) SysnodesTableManager(herddb.core.system.SysnodesTableManager) ArrayList(java.util.ArrayList) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) BRINIndexManager(herddb.index.brin.BRINIndexManager) SystablestatsTableManager(herddb.core.system.SystablestatsTableManager) BiConsumer(java.util.function.BiConsumer) CommitLogListener(herddb.log.CommitLogListener) ForeignKeyDef(herddb.model.ForeignKeyDef) IndexDoesNotExistException(herddb.model.IndexDoesNotExistException) TableSpaceManagerStats(herddb.core.stats.TableSpaceManagerStats) LogEntryType(herddb.log.LogEntryType) LogEntryFactory(herddb.log.LogEntryFactory) IOException(java.io.IOException) DataStorageManager(herddb.storage.DataStorageManager) DropIndexStatement(herddb.model.commands.DropIndexStatement) ColumnTypes(herddb.model.ColumnTypes) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Column(herddb.model.Column) KeyValue(herddb.utils.KeyValue) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) StampedLock(java.util.concurrent.locks.StampedLock) ServerHostData(herddb.network.ServerHostData) TableAlreadyExistsException(herddb.model.TableAlreadyExistsException) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) CreateTableStatement(herddb.model.commands.CreateTableStatement) TimeoutException(java.util.concurrent.TimeoutException) JMXUtils(herddb.jmx.JMXUtils) TransactionResult(herddb.model.TransactionResult) MetadataStorageManager(herddb.metadata.MetadataStorageManager) Channel(herddb.network.Channel) ServerConfiguration(herddb.server.ServerConfiguration) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) TableDoesNotExistException(herddb.model.TableDoesNotExistException) AlterTableStatement(herddb.model.commands.AlterTableStatement) SysindexcolumnsTableManager(herddb.core.system.SysindexcolumnsTableManager) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) StatementExecutionException(herddb.model.StatementExecutionException) Collection(java.util.Collection) SysstatementsTableManager(herddb.core.system.SysstatementsTableManager) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompletionException(java.util.concurrent.CompletionException) TableAwareStatement(herddb.model.TableAwareStatement) Logger(java.util.logging.Logger) EOFException(java.io.EOFException) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) HDBConnection(herddb.client.HDBConnection) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) SystransactionsTableManager(herddb.core.system.SystransactionsTableManager) NodeMetadata(herddb.model.NodeMetadata) Entry(java.util.Map.Entry) Optional(java.util.Optional) TableSpace(herddb.model.TableSpace) SysconfigTableManager(herddb.core.system.SysconfigTableManager) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) SysindexesTableManager(herddb.core.system.SysindexesTableManager) Statement(herddb.model.Statement) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) DataScannerException(herddb.model.DataScannerException) SystablespacesTableManager(herddb.core.system.SystablespacesTableManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Pdu(herddb.proto.Pdu) Level(java.util.logging.Level) HashSet(java.util.HashSet) SysclientsTableManager(herddb.core.system.SysclientsTableManager) TableChecksum(herddb.data.consistency.TableChecksum) ExecutorService(java.util.concurrent.ExecutorService) DumpedLogEntry(herddb.backup.DumpedLogEntry) SysforeignkeysTableManager(herddb.core.system.SysforeignkeysTableManager) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) CommitLog(herddb.log.CommitLog) ClientSideMetadataProvider(herddb.client.ClientSideMetadataProvider) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) SystablespacereplicastateTableManager(herddb.core.system.SystablespacereplicastateTableManager) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) StatementEvaluationContext(herddb.model.StatementEvaluationContext) SyscolumnsTableManager(herddb.core.system.SyscolumnsTableManager) Comparator(java.util.Comparator) Collections(java.util.Collections) TableManagerStats(herddb.core.stats.TableManagerStats) MemoryHashIndexManager(herddb.index.MemoryHashIndexManager) SystemProperties(herddb.utils.SystemProperties) AlterTableStatement(herddb.model.commands.AlterTableStatement) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) CreateTableStatement(herddb.model.commands.CreateTableStatement) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) TableAwareStatement(herddb.model.TableAwareStatement) StatementExecutionException(herddb.model.StatementExecutionException) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DropIndexStatement(herddb.model.commands.DropIndexStatement) Transaction(herddb.model.Transaction) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) ExecutionException(java.util.concurrent.ExecutionException) StatementExecutionException(herddb.model.StatementExecutionException) DropTableStatement(herddb.model.commands.DropTableStatement)

Example 27 with Transaction

use of herddb.model.Transaction in project herddb by diennea.

the class TableSpaceManager method checkpoint.

// visible for testing
public TableSpaceCheckpoint checkpoint(boolean full, boolean pin, boolean alreadLocked) throws DataStorageManagerException, LogNotAvailableException {
    if (virtual) {
        return null;
    }
    if (recoveryInProgress) {
        LOGGER.log(Level.INFO, "Checkpoint for tablespace {0} skipped. Recovery is still in progress", tableSpaceName);
        return null;
    }
    long _start = System.currentTimeMillis();
    LogSequenceNumber logSequenceNumber = null;
    LogSequenceNumber _logSequenceNumber = null;
    Map<String, LogSequenceNumber> checkpointsTableNameSequenceNumber = new HashMap<>();
    try {
        List<PostCheckpointAction> actions = new ArrayList<>();
        long lockStamp = 0;
        if (!alreadLocked) {
            lockStamp = acquireWriteLock("checkpoint");
        }
        try {
            logSequenceNumber = log.getLastSequenceNumber();
            if (logSequenceNumber.isStartOfTime()) {
                LOGGER.log(Level.INFO, "{0} checkpoint {1} at {2}. skipped (no write ever issued to log)", new Object[] { nodeId, tableSpaceName, logSequenceNumber });
                return new TableSpaceCheckpoint(logSequenceNumber, checkpointsTableNameSequenceNumber);
            }
            LOGGER.log(Level.INFO, "{0} checkpoint start {1} at {2}", new Object[] { nodeId, tableSpaceName, logSequenceNumber });
            if (actualLogSequenceNumber == null) {
                throw new DataStorageManagerException("actualLogSequenceNumber cannot be null");
            }
            // TODO: transactions checkpoint is not atomic
            Collection<Transaction> currentTransactions = new ArrayList<>(transactions.values());
            for (Transaction t : currentTransactions) {
                LogSequenceNumber txLsn = t.lastSequenceNumber;
                if (txLsn != null && txLsn.after(logSequenceNumber)) {
                    LOGGER.log(Level.SEVERE, "Found transaction {0} with LSN {1} in the future", new Object[] { t.transactionId, txLsn });
                }
            }
            actions.addAll(dataStorageManager.writeTransactionsAtCheckpoint(tableSpaceUUID, logSequenceNumber, currentTransactions));
            actions.addAll(writeTablesOnDataStorageManager(new CommitLogResult(logSequenceNumber, false, true), true));
            // we checkpoint all data to disk and save the actual log sequence number
            for (AbstractTableManager tableManager : tables.values()) {
                if (!tableManager.isSystemTable()) {
                    TableCheckpoint checkpoint = full ? tableManager.fullCheckpoint(pin) : tableManager.checkpoint(pin);
                    if (checkpoint != null) {
                        LOGGER.log(Level.INFO, "checkpoint done for table {0}.{1} (pin: {2})", new Object[] { tableSpaceName, tableManager.getTable().name, pin });
                        actions.addAll(checkpoint.actions);
                        checkpointsTableNameSequenceNumber.put(checkpoint.tableName, checkpoint.sequenceNumber);
                        if (afterTableCheckPointAction != null) {
                            afterTableCheckPointAction.run();
                        }
                    }
                }
            }
            // we are sure that all data as been flushed. upon recovery we will replay the log starting from this position
            actions.addAll(dataStorageManager.writeCheckpointSequenceNumber(tableSpaceUUID, logSequenceNumber));
            /* Indexes checkpoint is handled by TableManagers */
            if (leader) {
                log.dropOldLedgers(logSequenceNumber);
            }
            _logSequenceNumber = log.getLastSequenceNumber();
        } finally {
            if (!alreadLocked) {
                releaseWriteLock(lockStamp, "checkpoint");
            }
        }
        for (PostCheckpointAction action : actions) {
            try {
                action.run();
            } catch (Exception error) {
                LOGGER.log(Level.SEVERE, "postcheckpoint error:" + error, error);
            }
        }
        return new TableSpaceCheckpoint(logSequenceNumber, checkpointsTableNameSequenceNumber);
    } finally {
        long _stop = System.currentTimeMillis();
        LOGGER.log(Level.INFO, "{0} checkpoint finish {1} started ad {2}, finished at {3}, total time {4} ms", new Object[] { nodeId, tableSpaceName, logSequenceNumber, _logSequenceNumber, Long.toString(_stop - _start) });
        checkpointTimeStats.registerSuccessfulEvent(_stop, TimeUnit.MILLISECONDS);
    }
}
Also used : TableCheckpoint(herddb.core.AbstractTableManager.TableCheckpoint) DataStorageManagerException(herddb.storage.DataStorageManagerException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) LogSequenceNumber(herddb.log.LogSequenceNumber) CommitLogResult(herddb.log.CommitLogResult) HDBException(herddb.client.HDBException) IndexAlreadyExistsException(herddb.model.IndexAlreadyExistsException) LogNotAvailableException(herddb.log.LogNotAvailableException) ClientSideMetadataProviderException(herddb.client.ClientSideMetadataProviderException) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) IndexDoesNotExistException(herddb.model.IndexDoesNotExistException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) TableAlreadyExistsException(herddb.model.TableAlreadyExistsException) TimeoutException(java.util.concurrent.TimeoutException) DataStorageManagerException(herddb.storage.DataStorageManagerException) TableDoesNotExistException(herddb.model.TableDoesNotExistException) DDLException(herddb.model.DDLException) StatementExecutionException(herddb.model.StatementExecutionException) CompletionException(java.util.concurrent.CompletionException) EOFException(java.io.EOFException) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) DataScannerException(herddb.model.DataScannerException) Transaction(herddb.model.Transaction)

Example 28 with Transaction

use of herddb.model.Transaction in project herddb by diennea.

the class FileDataStorageManager method loadTransactions.

@Override
public void loadTransactions(LogSequenceNumber sequenceNumber, String tableSpace, Consumer<Transaction> consumer) throws DataStorageManagerException {
    try {
        Path tableSpaceDirectory = getTablespaceDirectory(tableSpace);
        Files.createDirectories(tableSpaceDirectory);
        Path file = getTablespaceTransactionsFile(tableSpace, sequenceNumber);
        boolean exists = Files.isRegularFile(file);
        LOGGER.log(Level.INFO, "loadTransactions " + sequenceNumber + " for tableSpace " + tableSpace + " from file " + file + " (exists: " + exists + ")");
        if (!exists) {
            return;
        }
        try (InputStream input = new BufferedInputStream(Files.newInputStream(file, StandardOpenOption.READ), 4 * 1024 * 1024);
            ExtendedDataInputStream din = new ExtendedDataInputStream(input)) {
            // version
            long version = din.readVLong();
            // flags for future implementations
            long flags = din.readVLong();
            if (version != 1 || flags != 0) {
                throw new DataStorageManagerException("corrupted transaction list file " + file.toAbsolutePath());
            }
            String readname = din.readUTF();
            if (!readname.equals(tableSpace)) {
                throw new DataStorageManagerException("file " + file.toAbsolutePath() + " is not for spablespace " + tableSpace);
            }
            long ledgerId = din.readZLong();
            long offset = din.readZLong();
            if (ledgerId != sequenceNumber.ledgerId || offset != sequenceNumber.offset) {
                throw new DataStorageManagerException("file " + file.toAbsolutePath() + " is not for sequence number " + sequenceNumber);
            }
            int numTransactions = din.readInt();
            for (int i = 0; i < numTransactions; i++) {
                Transaction tx = Transaction.deserialize(tableSpace, din);
                consumer.accept(tx);
            }
        }
    } catch (IOException err) {
        throw new DataStorageManagerException(err);
    }
}
Also used : Path(java.nio.file.Path) ExtendedDataInputStream(herddb.utils.ExtendedDataInputStream) DataStorageManagerException(herddb.storage.DataStorageManagerException) Transaction(herddb.model.Transaction) BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) ODirectFileInputStream(herddb.utils.ODirectFileInputStream) ExtendedDataInputStream(herddb.utils.ExtendedDataInputStream) SimpleByteArrayInputStream(herddb.utils.SimpleByteArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException)

Example 29 with Transaction

use of herddb.model.Transaction in project herddb by diennea.

the class SimpleClientServerTest method testKeepReadLocks.

@Test
public void testKeepReadLocks() throws Exception {
    Path baseDir = folder.newFolder().toPath();
    try (Server server = new Server(newServerConfigurationWithAutoPort(baseDir))) {
        server.start();
        server.waitForStandaloneBoot();
        ClientConfiguration clientConfiguration = new ClientConfiguration(folder.newFolder().toPath());
        try (HDBClient client = new HDBClient(clientConfiguration);
            HDBConnection connection = client.openConnection()) {
            client.setClientSideMetadataProvider(new StaticClientSideMetadataProvider(server));
            assertTrue(connection.waitForTableSpace(TableSpace.DEFAULT, Integer.MAX_VALUE));
            long resultCreateTable = connection.executeUpdate(TableSpace.DEFAULT, "CREATE TABLE mytable (id string primary key, n1 long, n2 integer)", 0, false, true, Collections.emptyList()).updateCount;
            Assert.assertEquals(1, resultCreateTable);
            long tx = connection.beginTransaction(TableSpace.DEFAULT);
            long countInsert = connection.executeUpdate(TableSpace.DEFAULT, "INSERT INTO mytable (id,n1,n2) values(?,?,?)", tx, false, true, Arrays.asList("test", 1, 2)).updateCount;
            Assert.assertEquals(1, countInsert);
            long countInsert2 = connection.executeUpdate(TableSpace.DEFAULT, "INSERT INTO mytable (id,n1,n2) values(?,?,?)", tx, false, true, Arrays.asList("test2", 2, 3)).updateCount;
            Assert.assertEquals(1, countInsert2);
            connection.commitTransaction(TableSpace.DEFAULT, tx);
            // new transaction
            tx = connection.beginTransaction(TableSpace.DEFAULT);
            // do not keep locks
            try (ScanResultSet scan = connection.executeScan(TableSpace.DEFAULT, "SELECT * FROM mytable WHERE id='test'", true, Collections.emptyList(), tx, 0, 10, false)) {
                Map<String, Object> record = scan.consume().get(0);
                assertEquals(RawString.of("test"), record.get("id"));
                assertEquals(Long.valueOf(1), record.get("n1"));
                assertEquals(Integer.valueOf(2), record.get("n2"));
                Transaction transaction = server.getManager().getTableSpaceManager(TableSpace.DEFAULT).getTransaction(tx);
                assertNull(transaction.lookupLock("mytable", Bytes.from_string("test")));
            }
            // keep locks
            try (ScanResultSet scan = connection.executeScan(TableSpace.DEFAULT, "SELECT * FROM mytable WHERE id='test'", true, Collections.emptyList(), tx, 0, 10, true)) {
                Map<String, Object> record = scan.consume().get(0);
                assertEquals(RawString.of("test"), record.get("id"));
                assertEquals(Long.valueOf(1), record.get("n1"));
                assertEquals(Integer.valueOf(2), record.get("n2"));
                Transaction transaction = server.getManager().getTableSpaceManager(TableSpace.DEFAULT).getTransaction(tx);
                assertFalse(transaction.lookupLock("mytable", Bytes.from_string("test")).write);
            }
            // upgrade lock to write
            try (ScanResultSet scan = connection.executeScan(TableSpace.DEFAULT, "SELECT * FROM mytable WHERE id='test' FOR UPDATE", true, Collections.emptyList(), tx, 0, 10, false)) {
                Map<String, Object> record = scan.consume().get(0);
                assertEquals(RawString.of("test"), record.get("id"));
                assertEquals(Long.valueOf(1), record.get("n1"));
                assertEquals(Integer.valueOf(2), record.get("n2"));
                Transaction transaction = server.getManager().getTableSpaceManager(TableSpace.DEFAULT).getTransaction(tx);
                assertTrue(transaction.lookupLock("mytable", Bytes.from_string("test")).write);
            }
            connection.rollbackTransaction(TableSpace.DEFAULT, tx);
            // new transaction
            tx = connection.beginTransaction(TableSpace.DEFAULT);
            // SELECT FOR UPDATE must hold WRITE LOCK even with keepLocks = false
            try (ScanResultSet scan = connection.executeScan(TableSpace.DEFAULT, "SELECT * FROM mytable WHERE id='test' FOR UPDATE", true, Collections.emptyList(), tx, 0, 10, false)) {
                Map<String, Object> record = scan.consume().get(0);
                assertEquals(RawString.of("test"), record.get("id"));
                assertEquals(Long.valueOf(1), record.get("n1"));
                assertEquals(Integer.valueOf(2), record.get("n2"));
                Transaction transaction = server.getManager().getTableSpaceManager(TableSpace.DEFAULT).getTransaction(tx);
                assertTrue(transaction.lookupLock("mytable", Bytes.from_string("test")).write);
            }
        }
    }
}
Also used : Path(java.nio.file.Path) StaticClientSideMetadataProvider(herddb.server.StaticClientSideMetadataProvider) Server(herddb.server.Server) Transaction(herddb.model.Transaction) RawString(herddb.utils.RawString) Test(org.junit.Test)

Example 30 with Transaction

use of herddb.model.Transaction in project herddb by diennea.

the class TableManager method apply.

@Override
public void apply(CommitLogResult writeResult, LogEntry entry, boolean recovery) throws DataStorageManagerException, LogNotAvailableException {
    if (recovery) {
        if (writeResult.deferred) {
            throw new DataStorageManagerException("impossibile to have a deferred CommitLogResult during recovery");
        }
        LogSequenceNumber position = writeResult.getLogSequenceNumber();
        if (dumpLogSequenceNumber != null && !position.after(dumpLogSequenceNumber)) {
            // in "restore mode" the 'position" parameter is from the 'old' transaction log
            Transaction transaction = null;
            if (entry.transactionId > 0) {
                transaction = tableSpaceManager.getTransaction(entry.transactionId);
            }
            if (transaction != null) {
                transaction.touch();
                LOGGER.log(Level.FINER, "{0}.{1} keep {2} at {3}, table restored from position {4}, it belongs to transaction {5} which was in progress during the dump of the table", new Object[] { table.tablespace, table.name, entry, position, dumpLogSequenceNumber, entry.transactionId });
            } else {
                LOGGER.log(Level.FINER, "{0}.{1} skip {2} at {3}, table restored from position {4}", new Object[] { table.tablespace, table.name, entry, position, dumpLogSequenceNumber });
                return;
            }
        } else if (!position.after(bootSequenceNumber)) {
            // recovery mode
            Transaction transaction = null;
            if (entry.transactionId > 0) {
                transaction = tableSpaceManager.getTransaction(entry.transactionId);
            }
            if (transaction != null) {
                transaction.touch();
                LOGGER.log(Level.FINER, "{0}.{1} keep {2} at {3}, table booted at {4}, it belongs to transaction {5} which was in progress during the flush of the table", new Object[] { table.tablespace, table.name, entry, position, bootSequenceNumber, entry.transactionId });
            } else {
                LOGGER.log(Level.FINER, "{0}.{1} skip {2} at {3}, table booted at {4}", new Object[] { table.tablespace, table.name, entry, position, bootSequenceNumber });
                return;
            }
        }
    }
    if (writeResult.sync) {
        // wait for data to be stored to log
        writeResult.getLogSequenceNumber();
    }
    switch(entry.type) {
        case LogEntryType.DELETE:
            {
                // remove the record from the set of existing records
                Bytes key = entry.key;
                if (entry.transactionId > 0) {
                    Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
                    if (transaction == null) {
                        /* Ignore missing transaction only if during recovery and ignore property is active */
                        if (recovery && ignoreMissingTransactionsOnRecovery) {
                            LOGGER.log(Level.WARNING, "Ignoring delete of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
                        } else {
                            throw new DataStorageManagerException("no such transaction " + entry.transactionId);
                        }
                    } else {
                        transaction.registerDeleteOnTable(this.table.name, key, writeResult);
                    }
                } else {
                    applyDelete(key);
                }
                break;
            }
        case LogEntryType.UPDATE:
            {
                Bytes key = entry.key;
                Bytes value = entry.value;
                if (entry.transactionId > 0) {
                    Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
                    if (transaction == null) {
                        /* Ignore missing transaction only if during recovery and ignore property is active */
                        if (recovery && ignoreMissingTransactionsOnRecovery) {
                            LOGGER.log(Level.WARNING, "Ignoring update of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
                        } else {
                            throw new DataStorageManagerException("no such transaction " + entry.transactionId);
                        }
                    } else {
                        transaction.registerRecordUpdate(this.table.name, key, value, writeResult);
                    }
                } else {
                    applyUpdate(key, value);
                }
                break;
            }
        case LogEntryType.INSERT:
            {
                Bytes key = entry.key;
                Bytes value = entry.value;
                if (entry.transactionId > 0) {
                    Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
                    if (transaction == null) {
                        /* Ignore missing transaction only if during recovery and ignore property is active */
                        if (recovery && ignoreMissingTransactionsOnRecovery) {
                            LOGGER.log(Level.WARNING, "Ignoring insert of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
                        } else {
                            throw new DataStorageManagerException("no such transaction " + entry.transactionId);
                        }
                    } else {
                        transaction.registerInsertOnTable(table.name, key, value, writeResult);
                    }
                } else {
                    applyInsert(key, value, false);
                }
                break;
            }
        case LogEntryType.TRUNCATE_TABLE:
            {
                applyTruncate();
            }
            break;
        default:
            throw new IllegalArgumentException("unhandled entry type " + entry.type);
    }
}
Also used : Bytes(herddb.utils.Bytes) DataStorageManagerException(herddb.storage.DataStorageManagerException) Transaction(herddb.model.Transaction) LogSequenceNumber(herddb.log.LogSequenceNumber)

Aggregations

Transaction (herddb.model.Transaction)43 DataStorageManagerException (herddb.storage.DataStorageManagerException)29 StatementExecutionException (herddb.model.StatementExecutionException)25 ArrayList (java.util.ArrayList)23 LogSequenceNumber (herddb.log.LogSequenceNumber)22 Table (herddb.model.Table)21 DDLException (herddb.model.DDLException)19 DataScanner (herddb.model.DataScanner)19 TransactionContext (herddb.model.TransactionContext)19 CommitLogResult (herddb.log.CommitLogResult)18 LogEntry (herddb.log.LogEntry)18 LogNotAvailableException (herddb.log.LogNotAvailableException)18 Index (herddb.model.Index)18 StatementExecutionResult (herddb.model.StatementExecutionResult)18 List (java.util.List)18 HashMap (java.util.HashMap)17 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)17 Map (java.util.Map)16 DataScannerException (herddb.model.DataScannerException)15 ScanStatement (herddb.model.commands.ScanStatement)15