summaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/server.c b/src/server.c
index faf010135..85c48c41d 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3304,29 +3304,35 @@ static void propagatePendingCommands() {
int j;
redisOp *rop;
- int multi_emitted = 0;
- /* Wrap the commands in server.also_propagate array,
- * but don't wrap it if we are already in MULTI context,
- * in case the nested MULTI/EXEC.
- *
- * And if the array contains only one command, no need to
- * wrap it, since the single command is atomic. */
- if (server.also_propagate.numops > 1) {
+ /* If we got here it means we have finished an execution-unit.
+ * If that unit has caused propagation of multiple commands, they
+ * should be propagated as a transaction */
+ int transaction = server.also_propagate.numops > 1;
+
+ /* In case a command that may modify random keys was run *directly*
+ * (i.e. not from within a script, MULTI/EXEC, RM_Call, etc.) we want
+ * to avoid using a transaction (much like active-expire) */
+ if (server.current_client &&
+ server.current_client->cmd &&
+ server.current_client->cmd->flags & CMD_TOUCHES_ARBITRARY_KEYS)
+ {
+ transaction = 0;
+ }
+
+ if (transaction) {
/* We use dbid=-1 to indicate we do not want to replicate SELECT.
* It'll be inserted together with the next command (inside the MULTI) */
propagateNow(-1,&shared.multi,1,PROPAGATE_AOF|PROPAGATE_REPL);
- multi_emitted = 1;
}
-
for (j = 0; j < server.also_propagate.numops; j++) {
rop = &server.also_propagate.ops[j];
serverAssert(rop->target);
propagateNow(rop->dbid,rop->argv,rop->argc,rop->target);
}
- if (multi_emitted) {
+ if (transaction) {
/* We use dbid=-1 to indicate we do not want to replicate select */
propagateNow(-1,&shared.exec,1,PROPAGATE_AOF|PROPAGATE_REPL);
}
@@ -4515,6 +4521,7 @@ void addReplyFlagsForCommand(client *c, struct redisCommand *cmd) {
{CMD_NO_MULTI, "no_multi"},
{CMD_MOVABLE_KEYS, "movablekeys"},
{CMD_ALLOW_BUSY, "allow_busy"},
+ /* {CMD_TOUCHES_ARBITRARY_KEYS, "TOUCHES_ARBITRARY_KEYS"}, Hidden on purpose */
{0,NULL}
};
addReplyCommandFlags(c, cmd->flags, flagNames);