use of herddb.model.commands.BeginTransactionStatement 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;
}
use of herddb.model.commands.BeginTransactionStatement in project herddb by diennea.
the class ServerSideConnectionPeer method beginTransaction.
public long beginTransaction(String tableSpace) throws HDBException {
try {
BeginTransactionStatement statement = new BeginTransactionStatement(tableSpace);
TransactionContext transactionContext = TransactionContext.NO_TRANSACTION;
return server.getManager().executeStatement(statement, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), transactionContext).transactionId;
} catch (HerdDBInternalException t) {
throw new HDBException(t);
}
}
use of herddb.model.commands.BeginTransactionStatement in project herddb by diennea.
the class SimpleRecoveryTest method createInsertInTransactionAndRestart.
@Test
public void createInsertInTransactionAndRestart() throws Exception {
Path dataPath = folder.newFolder("data").toPath();
Path logsPath = folder.newFolder("logs").toPath();
Path metadataPath = folder.newFolder("metadata").toPath();
Bytes key = Bytes.from_int(1234);
Bytes value = Bytes.from_long(8888);
Path tmoDir = folder.newFolder("tmoDir").toPath();
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
CreateTableStatement st2 = new CreateTableStatement(table);
manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.checkpoint();
long tx = ((TransactionResult) manager.executeStatement(new BeginTransactionStatement("tblspace1"), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)).getTransactionId();
InsertStatement insert = new InsertStatement("tblspace1", "t1", new Record(key, value));
assertEquals(1, manager.executeUpdate(insert, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx)).getUpdateCount());
manager.executeStatement(new CommitTransactionStatement("tblspace1", tx), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
}
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
manager.waitForTablespace("tblspace1", 10000);
GetStatement get = new GetStatement("tblspace1", "t1", key, null, false);
GetResult result = manager.get(get, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertTrue(result.found());
assertEquals(key, result.getRecord().key);
assertEquals(value, result.getRecord().value);
}
}
use of herddb.model.commands.BeginTransactionStatement in project herddb by diennea.
the class SimpleRecoveryTest method createInsertDeleteDifferentTransactionWithFlushTableAndRestart.
@Test
public void createInsertDeleteDifferentTransactionWithFlushTableAndRestart() throws Exception {
Path dataPath = folder.newFolder("data").toPath();
Path logsPath = folder.newFolder("logs").toPath();
Path metadataPath = folder.newFolder("metadata").toPath();
Bytes key = Bytes.from_int(1234);
Bytes key2 = Bytes.from_int(1235);
Bytes value = Bytes.from_long(8888);
Path tmoDir = folder.newFolder("tmoDir").toPath();
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
CreateTableStatement st2 = new CreateTableStatement(table);
manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
long tx = ((TransactionResult) manager.executeStatement(new BeginTransactionStatement("tblspace1"), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)).getTransactionId();
InsertStatement insert = new InsertStatement("tblspace1", "t1", new Record(key, value));
assertEquals(1, manager.executeUpdate(insert, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx)).getUpdateCount());
// flushing table data in the middle of the transaction
// the record will not be present in the snapshot of the table
manager.getTableSpaceManager("tblspace1").getTableManager("t1").flush();
manager.executeStatement(new CommitTransactionStatement("tblspace1", tx), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
long tx2 = ((TransactionResult) manager.executeStatement(new BeginTransactionStatement("tblspace1"), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)).getTransactionId();
DeleteStatement delete = new DeleteStatement("tblspace1", "t1", key, null);
assertEquals(1, manager.executeUpdate(delete, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx2)).getUpdateCount());
InsertStatement insert2 = new InsertStatement("tblspace1", "t1", new Record(key2, value));
assertEquals(1, manager.executeUpdate(insert2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx2)).getUpdateCount());
manager.executeStatement(new CommitTransactionStatement("tblspace1", tx2), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
}
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
manager.waitForTablespace("tblspace1", 10000);
{
GetStatement get = new GetStatement("tblspace1", "t1", key, null, false);
GetResult result = manager.get(get, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertFalse(result.found());
}
{
GetStatement get = new GetStatement("tblspace1", "t1", key2, null, false);
GetResult result = manager.get(get, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertTrue(result.found());
assertEquals(key2, result.getRecord().key);
assertEquals(value, result.getRecord().value);
}
}
}
use of herddb.model.commands.BeginTransactionStatement in project herddb by diennea.
the class SimpleRecoveryTest method rollbackCreateTableOnRestart.
@Test
public void rollbackCreateTableOnRestart() throws Exception {
Path dataPath = folder.newFolder("data").toPath();
Path logsPath = folder.newFolder("logs").toPath();
Path metadataPath = folder.newFolder("metadata").toPath();
Bytes key = Bytes.from_int(1234);
Bytes value = Bytes.from_long(8888);
Path tmoDir = folder.newFolder("tmoDir").toPath();
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
CreateTableStatement st2 = new CreateTableStatement(table);
manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.checkpoint();
Table transacted_table = Table.builder().tablespace("tblspace1").name("t2").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
long tx = ((TransactionResult) manager.executeStatement(new BeginTransactionStatement("tblspace1"), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)).getTransactionId();
CreateTableStatement st_create = new CreateTableStatement(transacted_table);
manager.executeStatement(st_create, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx));
InsertStatement insert = new InsertStatement("tblspace1", "t2", new Record(key, value));
assertEquals(1, manager.executeUpdate(insert, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx)).getUpdateCount());
GetStatement get = new GetStatement("tblspace1", "t2", key, null, false);
GetResult result = manager.get(get, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx));
assertTrue(result.found());
assertEquals(key, result.getRecord().key);
assertEquals(value, result.getRecord().value);
// transaction is not committed, and the leader dies, the table will disappear
}
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath), tmoDir, null)) {
manager.start();
manager.waitForTablespace("tblspace1", 10000);
GetStatement get = new GetStatement("tblspace1", "t2", key, null, false);
try {
manager.get(get, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
fail();
} catch (TableDoesNotExistException error) {
}
}
}
Aggregations