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" ) ) ); }
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(); }