使用带redis-py的锁

时间:2015-12-09 05:21:33

标签: python django redis

我试图在django项目中创建redis值的锁定,但遇到了麻烦。非阻塞代码工作正常,即:

r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
r.hmset('hash', data_dict)

但是当尝试使用锁来阻止其他线程写入此代码时,使用代码:

r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
lock = r.lock('hash')
with lock.acquire() as l:
    r.hmset('hash', data_dict)

抛出:redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value

如果这是一个非常愚蠢的问题我很抱歉,但我不明白我是如何得到这个错误的,所设置的数据实际上是相同的

2 个答案:

答案 0 :(得分:3)

您正尝试在与锁相同的密钥中设置字典。你想要一个锁的钥匙和另一个锁的字典。

答案 1 :(得分:3)

有两个问题:

  1. 正如其他人所说,您需要为锁和哈希使用两个不同的键。
  2. 语法错误。

要详细说明第2点,以下是使用锁涉及的步骤:

  1. 创建一个public class StatusDaoImpl implements StatusDao { public void setDataSource(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } @Override public void statusLookUp(String id) throws DaoException { DataSource ds = null; Connection conn = null; PreparedStatement pstmt = null; CallableStatement cStmt = null; ResultSet rs = null; try { ds = jdbcTemplate.getDataSource(); conn = ds.getConnection(); cStmt = conn.prepareCall("{call STATUS_RETRIEVER.GET_STATUS(?)}"); cStmt.setString(1, id); cStmt.registerOutParameter(2, Types.VARCHAR); int uniqueId = cStmt.getInt(2); pstmt = conn.prepareStatement("SELECT STATUS FROM STATUS_CHECK WHERE uniqueuId=?"); pstmt.setInt(1, uniqueId); rs = pstmt.executeQuery(); rs.next(); String status = rs.getString("STATUS"); System.out.println("The status received is as follows:"); System.out.println(status); } catch (Throwable th) { throw new DaoException(th.getMessage(), th); } } } 对象。
  2. 获取锁。
  3. 做重要的事情。
  4. 释放锁。

不使用上下文管理器(Lock语句),代码可能如下所示:

with ...

使用上下文管理器,该代码简化为:

lock = r.lock('my_lock')
lock.acquire(blocking=True)
r.set('foo', 'bar')
lock.release()

这是怎么回事:

  1. with r.lock('my_lock'): r.set('foo', 'bar') 创建并返回一个r.lock()对象。
  2. Lock被自动调用,依次调用Lock.__enter__()
  3. 执行缩进的代码。
  4. Lock.acquire()被自动调用,依次调用Lock.__exit__()

您可以在 redis-py 源代码中看到它。