use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.
the class TorodbSafeRequestProcessor method execute.
@Override
public <A, R> Status<R> execute(Request req, Command<? super A, ? super R> command, A arg, MongodConnection connection) {
mongodMetrics.getCommands().mark();
Timer timer = mongodMetrics.getTimer(command);
try (Timer.Context ctx = timer.time()) {
Callable<Status<R>> callable;
RequiredTransaction commandType = commandsLibrary.getCommandType(command);
switch(commandType) {
case NO_TRANSACTION:
callable = () -> {
return connection.getCommandsExecutor().execute(req, command, arg, connection);
};
break;
case READ_TRANSACTION:
callable = () -> {
try (ReadOnlyMongodTransaction trans = connection.openReadOnlyTransaction()) {
return trans.execute(req, command, arg);
}
};
break;
case WRITE_TRANSACTION:
callable = () -> {
try (WriteMongodTransaction trans = connection.openWriteTransaction(true)) {
Status<R> result = trans.execute(req, command, arg);
if (result.isOk()) {
trans.commit();
}
return result;
}
};
break;
case EXCLUSIVE_WRITE_TRANSACTION:
callable = () -> {
try (ExclusiveWriteMongodTransaction trans = connection.openExclusiveWriteTransaction(true)) {
Status<R> result = trans.execute(req, command, arg);
if (result.isOk()) {
trans.commit();
}
return result;
}
};
break;
default:
throw new AssertionError("Unexpected command type" + commandType);
}
try {
return retrier.retry(callable);
} catch (RetrierGiveUpException ex) {
return Status.from(ErrorCode.CONFLICTING_OPERATION_IN_PROGRESS, "It was impossible to execute " + command.getCommandName() + " after several attempts");
}
}
}
use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.
the class SimpleAnalyzedOplogBatchExecutor method execute.
@Override
public void execute(OplogOperation op, ApplierContext context) throws OplogApplyingException, RollbackException, UserException {
try (MongodConnection connection = server.openConnection();
ExclusiveWriteMongodTransaction mongoTransaction = connection.openExclusiveWriteTransaction()) {
oplogOperationApplier.apply(op, mongoTransaction, context);
mongoTransaction.commit();
}
}
use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.
the class ReplSyncApplier method runProtected.
@Override
protected void runProtected() {
runThread = Thread.currentThread();
/*
* TODO: In general, the replication context can be set as not reaplying. But it is not frequent
* but possible to stop the replication after some oplog ops have been apply but not marked as
* executed on the oplog manager. For that reason, all oplog ops betwen the last operation that
* have been marked as applyed and the current last operation on the remote oplog must be
* executed as replying operations. As it is not possible to do that yet, we have to always
* apply operations as replying to be safe.
*/
ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
while (isRunning()) {
OplogOperation lastOperation = null;
ExclusiveWriteMongodTransaction trans = connection.openExclusiveWriteTransaction();
try (ExclusiveWriteMongodTransaction transaction = trans) {
try {
for (OplogOperation opToApply : callback.takeOps()) {
lastOperation = opToApply;
LOGGER.trace("Executing {}", opToApply);
try {
boolean done = false;
while (!done) {
try {
oplogOpApplier.apply(opToApply, transaction, applierContext);
transaction.commit();
done = true;
} catch (RollbackException ex) {
LOGGER.debug("Recived a rollback exception while applying an oplog op", ex);
}
}
} catch (OplogApplyingException ex) {
if (!callback.failedToApply(opToApply, ex)) {
LOGGER.error(serviceName() + " stopped because one operation " + "cannot be executed", ex);
break;
}
} catch (UserException ex) {
if (callback.failedToApply(opToApply, ex)) {
LOGGER.error(serviceName() + " stopped because one operation " + "cannot be executed", ex);
break;
}
} catch (Throwable ex) {
if (callback.failedToApply(opToApply, ex)) {
LOGGER.error(serviceName() + " stopped because " + "an unknown error", ex);
break;
}
}
callback.markAsApplied(opToApply);
}
} catch (InterruptedException ex) {
LOGGER.debug("Interrupted applier thread while applying an operator");
}
}
if (lastOperation != null) {
try (WriteOplogTransaction oplogTransaction = oplogManager.createWriteTransaction()) {
oplogTransaction.addOperation(lastOperation);
} catch (OplogManagerPersistException ex) {
if (callback.failedToApply(lastOperation, ex)) {
LOGGER.error(serviceName() + " stopped because " + "the last applied operation couldn't " + "be persisted", ex);
break;
}
}
}
}
}
Aggregations