示例#1
0
    bool WriteBatchExecutor::ExecInsertsState::_lockAndCheckImpl(WriteOpResult* result) {
        if (hasLock()) {
            txn->getCurOp()->enter(_context.get());
            return true;
        }

        invariant(!_context.get());
        _writeLock.reset(new Lock::DBLock(txn->lockState(),
                                          nsToDatabase(request->getNS()),
                                          newlm::MODE_X));
        if (!checkIsMasterForDatabase(request->getNS(), result)) {
            return false;
        }
        if (!checkShardVersion(txn, &shardingState, *request, result)) {
            return false;
        }
        if (!checkIndexConstraints(txn, &shardingState, *request, result)) {
            return false;
        }

        _context.reset(new Client::Context(txn, request->getNS(), false));

        Database* database = _context->db();
        dassert(database);
        _collection = database->getCollection(txn, request->getTargetingNS());
        if (!_collection) {
            WriteUnitOfWork wunit (txn);
            // Implicitly create if it doesn't exist
            _collection = database->createCollection(txn, request->getTargetingNS());
            if (!_collection) {
                result->setError(
                        toWriteError(Status(ErrorCodes::InternalError,
                                            "could not create collection " +
                                            request->getTargetingNS())));
                return false;
            }
            repl::logOp(txn,
                        "c",
                        (database->name() + ".$cmd").c_str(),
                        BSON("create" << nsToCollectionSubstring(request->getTargetingNS())));
            wunit.commit();
        }
        return true;
    }
 void run() {
     WriteUnitOfWork wunit (&_txn);
     // Insert some documents.
     int32_t nDocs = 1000;
     for( int32_t i = 0; i < nDocs; ++i ) {
         _client.insert( _ns, BSON( "a" << i ) );
     }
     // Initialize curop.
     _txn.getCurOp()->reset();
     // Request an interrupt.
     getGlobalEnvironment()->setKillAllOperations();
     // The call is not interrupted.
     Helpers::ensureIndex( &_txn, collection(), BSON( "a" << 1 ), false, "a_1" );
     // only want to interrupt the index build
     wunit.commit();
     getGlobalEnvironment()->unsetKillAllOperations();
     // The new index is listed in system.indexes because the index build completed.
     ASSERT_EQUALS( 1U,
                    _client.count( "unittests.system.indexes",
                                   BSON( "ns" << _ns << "name" << "a_1" ) ) );
 }
示例#3
0
static void insertOne(WriteBatchExecutor::ExecInsertsState* state, WriteOpResult* result) {
    invariant(state->currIndex < state->normalizedInserts.size());
    const StatusWith<BSONObj>& normalizedInsert(state->normalizedInserts[state->currIndex]);

    if (!normalizedInsert.isOK()) {
        result->setError(toWriteError(normalizedInsert.getStatus()));
        return;
    }

    const BSONObj& insertDoc = normalizedInsert.getValue().isEmpty() ?
                               state->request->getInsertRequest()->getDocumentsAt( state->currIndex ) :
                               normalizedInsert.getValue();

    try {
        if (state->lockAndCheck(result)) {
            WriteUnitOfWork wunit (state->txn->recoveryUnit());
            if (!state->request->isInsertIndexRequest()) {
                singleInsert(state->txn, insertDoc, state->getCollection(), result);
            }
            else {
                singleCreateIndex(state->txn, insertDoc, state->getCollection(), result);
            }
            wunit.commit();
        }
    }
    catch (const DBException& ex) {
        Status status(ex.toStatus());
        if (ErrorCodes::isInterruption(status.code()))
            throw;
        result->setError(toWriteError(status));
    }

    // Errors release the write lock, as a matter of policy.
    if (result->getError())
        state->unlock();
}