Я сталкиваюсь с некоторым странным поведением в конвейере / транзакции в Redis, что заставляет меня усомниться в том, что код фактически выполняется в транзакции:
class RedisThread:
KEY = "threading_test"
def __init__(self, id:int):
self._redis = Redis(host="localhost", port=6379, db=0)
self._id = id
self._redis.delete(self.KEY)
def __call__(self, *args, **kwargs):
results = []
for i in range(3):
# Transaction
pipe = self._redis.pipeline(transaction=True)
# ZADD current time as score
pipe.zadd(self.KEY, {f"{self._id}-{i}": time.time()})
# ZRANK
pipe.zrank(self.KEY, f"{self._id}-{i}")
# Commit and get result of ZRANK
results.append(str(pipe.execute()[1]))
print(", ".join(results))
threads = [
threading.Thread(target=RedisThread(1)),
threading.Thread(target=RedisThread(2)),
threading.Thread(target=RedisThread(3)),
threading.Thread(target=RedisThread(4)),
threading.Thread(target=RedisThread(5)),
]
for t in threads:
t.start()
for t in threads:
t.join()
Когда я запускаю этот код, это результат:
1, 5, 9
3, 6, 10
0, 3, 13
4, 11, 12
1, 4, 13
Обратите внимание, что между потоками есть повторяющиеся значения. Так как я делаю ZRANK, и значения, которые я добавляю (через ZADD) к набору, основаны на времени (и, следовательно, всегда увеличиваются в значениях), я не должен видеть никаких дубликатов, хотя есть дубликаты ...