diff options
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 29 |
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); |