SERVER-120912: Support w:n for n>1 for DSC (#52647)

GitOrigin-RevId: b5186a1aeeea6e347c92dd6f6f66b5db03ca7b15
This commit is contained in:
Lyublena Antova 2026-05-19 09:57:32 +03:00 committed by MongoDB Bot
parent 5b8d5a4c78
commit 1e16cdf1d6
3 changed files with 52 additions and 33 deletions

View File

@ -9,6 +9,7 @@
// TODO (SERVER-39704): Remove the following load after SERVER-39704 is completed
import {retryOnceOnTransientOnMongos} from "jstests/libs/auto_retry_transaction_in_sharding.js";
import {PersistenceProviderUtil} from "jstests/libs/server-rss/persistence_provider_util.js";
const dbName = "test";
const collName = "multi_statement_transaction_abort";
@ -305,39 +306,43 @@ assert.commandWorked(
}),
);
jsTest.log("Aborting transaction attempts to wait for write concern.");
txnNumber++;
assert.commandWorked(
sessionDb.runCommand({
insert: collName,
documents: [{a: 1}],
txnNumber: NumberLong(txnNumber),
startTransaction: true,
autocommit: false,
}),
);
assert.commandFailedWithCode(
sessionDb.adminCommand({
abortTransaction: 1,
txnNumber: NumberLong(txnNumber),
writeConcern: {w: 40},
autocommit: false,
}),
ErrorCodes.UnsatisfiableWriteConcern,
);
// In disagg, w:N (N>1) is remapped to majority, so the abort below would succeed rather than
// fail with UnsatisfiableWriteConcern. Skip this block in disagg.
if (PersistenceProviderUtil.allNodesHavePropertyWithValue(db, "supportsLocalCollections", true)) {
jsTest.log("Aborting transaction attempts to wait for write concern.");
txnNumber++;
assert.commandWorked(
sessionDb.runCommand({
insert: collName,
documents: [{a: 1}],
txnNumber: NumberLong(txnNumber),
startTransaction: true,
autocommit: false,
}),
);
assert.commandFailedWithCode(
sessionDb.adminCommand({
abortTransaction: 1,
txnNumber: NumberLong(txnNumber),
writeConcern: {w: 40},
autocommit: false,
}),
ErrorCodes.UnsatisfiableWriteConcern,
);
// TODO (SLS-2341): Remove cleanup abort once w:n write concern is supported.
// On a replica set, the failed abort above leaves the transaction in a dangling state because only
// the write concern was unsatisfiable, not the abort itself. Abort it properly here to ensure the
// transaction releases its locks before ending the session. On a sharded cluster, the transaction
// may already be aborted, so we also accept NoSuchTransaction.
assert.commandWorkedOrFailedWithCode(
sessionDb.adminCommand({
abortTransaction: 1,
txnNumber: NumberLong(txnNumber),
autocommit: false,
}),
ErrorCodes.NoSuchTransaction,
);
// TODO (SLS-2341): Remove cleanup abort once w:n write concern is supported.
// On a replica set, the failed abort above leaves the transaction in a dangling state because only
// the write concern was unsatisfiable, not the abort itself. Abort it properly here to ensure the
// transaction releases its locks before ending the session. On a sharded cluster, the transaction
// may already be aborted, so we also accept NoSuchTransaction.
assert.commandWorkedOrFailedWithCode(
sessionDb.adminCommand({
abortTransaction: 1,
txnNumber: NumberLong(txnNumber),
autocommit: false,
}),
ErrorCodes.NoSuchTransaction,
);
}
session.endSession();

View File

@ -73,6 +73,8 @@
namespace mongo {
std::function<void(WriteConcernOptions&)> remapWriteConcernHook;
using repl::OpTime;
using std::string;
@ -214,6 +216,10 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx,
}
}
if (remapWriteConcernHook) {
remapWriteConcernHook(writeConcern);
}
Status wcStatus = validateWriteConcern(opCtx, writeConcern);
if (!wcStatus.isOK()) {
return wcStatus;

View File

@ -41,6 +41,7 @@
#include "mongo/util/modules.h"
#include "mongo/util/net/hostandport.h"
#include <functional>
#include <string>
#include <vector>
@ -59,6 +60,13 @@ class OpTime;
*/
bool commandSpecifiesWriteConcern(const GenericArguments& requestArgs);
/**
* Optional hook to remap write concern options before validation. Modules that restrict supported
* write concerns (e.g. DSC) may set this at startup to transparently remap
* unsupported values (such as w:N for N>1) to an equivalent supported form.
*/
extern std::function<void(WriteConcernOptions&)> remapWriteConcernHook;
/**
* Attempts to extract a WriteConcernOptions from a command's generic arguments.
* Verifies that the resulting writeConcern is valid for this particular host.