Вы можете использовать транзакцию, чтобы команды DEL и RPU SH выполнялись атомарно. См. CLIENT.MULTI ([COMMANDS]) .
. Вы можете добавить WATCH для своего ключа, если хотите, чтобы транзакция не выполнялась, если ваш список был изменен во время обработки. См. ОПТИМИСТИ C ЗАМКИ . Но в этом случае вам потребуется логика восстановления / повторных попыток c в случае сбоя.
Чтобы использовать WATCH
, вы сначала начинаете просмотр, затем читаете список с помощью LRANGE
, выполняете манипуляции, затем выполняете MULTI
, DEL
, RPUSH
, EXEC
. EXE C завершится ошибкой, если список был изменен между WATCH
и EXEC
.
client.watch(key, function( err ){
if(err) throw err;
client.lrange(key, 0, -1, function(err, result) {
if(err) throw err;
// Process the result
client.multi()
.del(key)
.rpush(key, newItems)
.exec(function(err, results) {
/**
* If err is null, it means Redis successfully attempted
* the operation.
*/
if(err) throw err;
/**
* If results === null, it means that a concurrent client
* changed the key while we were processing it and thus
* the execution of the MULTI command was not performed.
*
* NOTICE: Failing an execution of MULTI is not considered
* an error. So you will have err === null and results === null
*/
});
});
});
RPUSH
в Redis поддерживает несколько элементов одновременно. Рассмотрите возможность одновременной загрузки нескольких элементов, используя [send_command][3]
, прямой синтаксис ES6 или прямую передачу массива (зависит от используемой версии).
Тем не менее, рассмотрите возможность использования Lua скрипты. Вот немного pu sh, чтобы вы начали:
EVAL "local list1 = redis.call('LRANGE', KEYS[1], 0, -1) for ix,elm in ipairs(list1) do list1[ix] = string.gsub(elm, 'node', 'nodejs') end redis.call('DEL', KEYS[1]) redis.call('RPUSH', KEYS[1], unpack(list1)) return list1" 1 myList
Здесь дружественный взгляд на сценарий Lua:
local list1 = redis.call('LRANGE', KEYS[1], 0, -1)
for ix,elm in ipairs(list1) do
list1[ix] = string.gsub(elm, 'node', 'nodejs')
end
redis.call('DEL', KEYS[1])
redis.call('RPUSH', KEYS[1], unpack(list1))
return list1
Это просто заменяет node
на nodejs
во всех элементах списка. Подробнее о работе со строками читайте в Обучающем руководстве по библиотеке строк .