python - Redis 对象映射器的原子事务?
问题描述
我一直在使用 josiahcarlson 的 Redis Object Mapper (ROM) 来处理我在 Redis 中的数据。我需要将某些操作作为事务完成,即所有写入都已完成或没有完成(在出现任何错误或关闭时自动回滚)。
据我在网上查到,Josiah 和 Redis 的维护者有过对话,后者在 2015 年不同意接受 PR 进行交易,现在情况如何?我在文档和 Google 中都找不到任何关于此的内容。
如何使用 ROM 为我的操作实现原子性?有办法吗?
解决方案
它以前没有内置到 rom(早期版本)中。如果您想快速轻松地进行操作,我们会将临时事务 ID 保存在一个公共位置(如果需要,您可以在之后验证)。如果你想正式,你会想要一个交易历史/分类账,这需要更多的工作(你可以使用分类账模型来存储价值,然后将其标记为已完成作为交易的一部分)。
如果你想使用内置功能和你自己的模型数据来传输,你可以使用我们在测试中的东西:https://github.com/josiahcarlson/rom/blob/1.0.0/test/test_rom。 py#L1759
下面的函数将传递一个值,并刷新您的本地模型。退货(successful_transfer, optional_message)
。
def transfer(source, dest, column, value, txn_set, txn_id, timeout=1, column_indexed=False):
source_key = source._pk
dest_key = dest._pk
# assume source and dest have same connection
c = source._connection.pipeline(True)
assert value > 0, value
end = time.time() + timeout
while time.time() < end:
c.watch(source_key, dest_key, txn_set)
if c.sismember(txn_set, txn_id):
return False, "already sent"
v = type(value)(c.hget(source, column) or 0)
if v < value:
c.discard()
return False, "not enough credit"
try:
c.multi()
c.hincrby(source_key, column, -value)
c.hincrby(dest_key, column, value)
c.sadd(txn_set, txn_id)
r = c.execute()
assert not r[-1], r
source.refresh()
dest.refresh()
bd = []
if column_indexed:
try:
source.save(full=True)
except:
bd.append("source index update failed")
try:
dest.save(full=True)
except:
bd.append("dest index update failed")
if bd:
bd.append("value transferred")
return True, ", ".join(bd)
except redis.exceptions.WatchError:
continue
return False, "timed out from data race condition"
推荐阅读
- php - 如何显示来自特定类别的文章而不是所有文章
- c# - 使用剃须刀页面覆盖 .net core 2 中的授权策略
- python - 是否可以将 python 库(以及与之相关的底层库)从一台计算机移植到另一台计算机?
- java - 如何使用 JSch 仅获取文件名?
- java - 确定一对字符串中的任何一个是否结束另一个字符串
- tensorflow - Adam opitmizer 中的 epsilon 参数
- angular - 路由页面时菜单切换不起作用
- xamarin - Xamarin Forms Android 关闭时未收到推送通知
- node.js - 由于 node-sass 错误,Ionic 无法构建应用程序
- c# - C#线程读写文件