use of herddb.model.TransactionResult in project herddb by diennea.
the class TableSpaceManager method commitTransaction.
private CompletableFuture<StatementExecutionResult> commitTransaction(CommitTransactionStatement statement, StatementEvaluationContext context) throws StatementExecutionException {
long txId = statement.getTransactionId();
validateTransactionBeforeTxCommand(txId);
LogEntry entry = LogEntryFactory.commitTransaction(txId);
long lockStamp = context.getTableSpaceLock();
boolean lockAcquired = false;
if (lockStamp == 0) {
lockStamp = acquireReadLock(statement);
context.setTableSpaceLock(lockStamp);
lockAcquired = true;
}
CommitLogResult pos = log.log(entry, true);
CompletableFuture<StatementExecutionResult> res = pos.logSequenceNumber.handleAsync((lsn, error) -> {
if (error == null) {
apply(pos, entry, false);
return new TransactionResult(txId, TransactionResult.OutcomeType.COMMIT);
} else {
// if the log is not able to write the commit
// apply a dummy "rollback", we are no more going to accept commands
// in the scope of this transaction
LogEntry rollback = LogEntryFactory.rollbackTransaction(txId);
apply(new CommitLogResult(LogSequenceNumber.START_OF_TIME, false, false), rollback, false);
throw new CompletionException(error);
}
}, callbacksExecutor);
if (lockAcquired) {
res = releaseReadLock(res, lockStamp, statement).thenApply(s -> {
context.setTableSpaceLock(0);
return s;
});
}
return res;
}
use of herddb.model.TransactionResult in project herddb by diennea.
the class ServerSideConnectionPeer method handleExecuteStatement.
private void handleExecuteStatement(Pdu message, Channel channel) {
long txId = PduCodec.ExecuteStatement.readTx(message);
String tablespace = PduCodec.ExecuteStatement.readTablespace(message);
long statementId = PduCodec.ExecuteStatement.readStatementId(message);
String query = statementId > 0 ? preparedStatements.resolveQuery(tablespace, statementId) : PduCodec.ExecuteStatement.readQuery(message);
if (query == null) {
ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
channel.sendReplyMessage(message.messageId, error);
message.close();
return;
}
boolean returnValues = PduCodec.ExecuteStatement.readReturnValues(message);
PduCodec.ObjectListReader parametersReader = PduCodec.ExecuteStatement.startReadParameters(message);
List<Object> parameters = new ArrayList<>(parametersReader.getNumParams());
for (int i = 0; i < parametersReader.getNumParams(); i++) {
parameters.add(parametersReader.nextObject());
}
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "query {0} with {1}", new Object[] { query, parameters });
}
RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tablespace, "", 1);
TransactionContext transactionContext = new TransactionContext(txId);
TranslatedQuery translatedQuery;
try {
translatedQuery = server.getManager().getPlanner().translate(tablespace, query, parameters, false, true, returnValues, -1);
} catch (StatementExecutionException ex) {
ByteBuf error = composeErrorResponse(message.messageId, ex);
channel.sendReplyMessage(message.messageId, error);
message.close();
return;
}
Statement statement = translatedQuery.plan.mainStatement;
// LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", plan: " + translatedQuery.plan);
RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
runningStatements.registerRunningStatement(statementInfo);
CompletableFuture<StatementExecutionResult> res = server.getManager().executePlanAsync(translatedQuery.plan, translatedQuery.context, transactionContext);
// LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", result:" + result);
res.whenComplete((result, err) -> {
try {
runningStatements.unregisterRunningStatement(statementInfo);
if (err != null) {
while (err instanceof CompletionException) {
err = err.getCause();
}
if (err instanceof DuplicatePrimaryKeyException) {
ByteBuf error = PduCodec.ErrorResponse.writeSqlIntegrityConstraintsViolation(message.messageId, new SQLIntegrityConstraintViolationException(err));
channel.sendReplyMessage(message.messageId, error);
} else if (err instanceof NotLeaderException) {
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
} else if (err instanceof StatementExecutionException) {
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
} else {
LOGGER.log(Level.SEVERE, "unexpected error on query " + query + ", parameters: " + parameters + ":" + err, err);
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
}
return;
}
if (result instanceof DMLStatementExecutionResult) {
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
Map<String, Object> newRecord = null;
if (returnValues && dml.getKey() != null) {
TableAwareStatement tableStatement = statement.unwrap(TableAwareStatement.class);
Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
newRecord = new HashMap<>();
Object newKey = RecordSerializer.deserializePrimaryKey(dml.getKey(), table);
newRecord.put("_key", newKey);
if (dml.getNewvalue() != null) {
newRecord.putAll(RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table));
}
}
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, dml.getUpdateCount(), dml.transactionId, newRecord));
} else if (result instanceof GetResult) {
GetResult get = (GetResult) result;
if (!get.found()) {
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 0, get.transactionId, null));
} else {
Map<String, Object> record = get.getRecord().toBean(get.getTable());
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, get.transactionId, record));
}
} else if (result instanceof TransactionResult) {
TransactionResult txresult = (TransactionResult) result;
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, txresult.getTransactionId(), null));
} else if (result instanceof DDLStatementExecutionResult) {
DDLStatementExecutionResult ddl = (DDLStatementExecutionResult) result;
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 1, ddl.transactionId, null));
} else if (result instanceof DataConsistencyStatementResult) {
channel.sendReplyMessage(message.messageId, PduCodec.ExecuteStatementResult.write(message.messageId, 0, 0, null));
} else {
ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unknown result type:" + result);
channel.sendReplyMessage(message.messageId, error);
}
} finally {
message.close();
}
});
}
use of herddb.model.TransactionResult in project herddb by diennea.
the class TableSpaceManager method beginTransactionAsync.
private CompletableFuture<StatementExecutionResult> beginTransactionAsync(StatementEvaluationContext context, boolean releaseLock) throws StatementExecutionException {
long id = newTransactionId.incrementAndGet();
LogEntry entry = LogEntryFactory.beginTransaction(id);
CommitLogResult pos;
boolean lockAcquired = false;
if (context.getTableSpaceLock() == 0) {
long lockStamp = acquireReadLock("begin transaction");
context.setTableSpaceLock(lockStamp);
lockAcquired = true;
}
pos = log.log(entry, false);
CompletableFuture<StatementExecutionResult> res = pos.logSequenceNumber.thenApplyAsync((lsn) -> {
apply(pos, entry, false);
return new TransactionResult(id, TransactionResult.OutcomeType.BEGIN);
}, callbacksExecutor);
if (lockAcquired && releaseLock) {
releaseReadLock(res, context.getTableSpaceLock(), "begin transaction");
}
return res;
}
use of herddb.model.TransactionResult 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.TransactionResult 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);
}
}
}
Aggregations