【发布时间】:2011-12-18 01:51:31
【问题描述】:
我希望我的问题是如何开始的
取一张有 26 个键 a-z 的表,并让它们具有整数值。 创建一个流程,哎呀,一遍又一遍地做两件事
- 在一个事务中,为 a、b 和 c 写入随机值,使这些值总是总和为 10
- 在另一个事务中,读取 a、b 和 c 的值,如果它们的值之和不等于 10,则抱怨
如果您启动其中的几个进程,您会很快看到 a、b 和 c 处于一种状态它们的值总和不等于 10。我相信没有办法要求 mnesia“在开始写入(或读取)之前锁定这 3 条记录”,只能让 mnesia 将记录锁定为它到达了它们(可以这么说),这允许记录集的值违反我的“必须总和为 10”约束。
如果我是对的,这个问题的解决方案包括
- 在写入(或读取)这组 3 条记录之前锁定整个表 -- 我讨厌为 3 条记录锁定整个表,
- 创建一个进程来跟踪谁在读取或写入哪些密钥,并保护批量操作不被其他任何人写入或读取,直到操作完成。当然,我必须确保所有进程都使用这个......废话,我想这意味着编写我自己的 AccessMod 作为 activity/4 的第四个参数,这似乎是一个不平凡的练习
- 我还不够聪明,无法弄清楚的其他一些事情。
想法?
好的,我是一个雄心勃勃的 Erlang 新手,如果这是一个愚蠢的问题,很抱歉,但是
我正在构建一个特定于应用程序的内存中分布式缓存,我需要能够在一个事务中编写 Key、Value 对集,并在一个事务中检索值集。换句话说,我需要 1) 将 40 个 key,value 对写入缓存中,并确保在此多键写入操作期间,没有其他人可以读取或写入这 40 个键中的任何一个;和, 2) 在一次操作中读取 40 个键并返回 40 个值,因为从该读取操作开始到结束,所有 40 个值都没有改变。
我能想到的唯一方法是在 fetch_keylist([ListOfKeys]) 的开头或 write_keylist([KeyValuePairs] 的开头锁定整个表,但我不想这样做因为我有许多进程同时进行自己的 multi_key 读取和写入,我不想在任何进程需要读取/写入相对较小的记录子集时锁定整个表。
帮助?
想更清楚一点:我不认为这只是使用普通交易
我认为我在问一个比这更微妙的问题。想象一下,我有一个进程,在事务中迭代 10 条记录,并在执行过程中锁定它们。现在想象这个过程开始了,但在它迭代到第三条记录之前,另一个过程更新了第三条记录。就事务而言,这会很好,因为第一个进程还没有锁定第三条记录(还),而 OTHER 进程在第一个进程到达之前对其进行了修改并释放了它。我想要保证的是,一旦我的第一个进程开始,在第一个进程完成之前,没有其他进程可以触及这 10 条记录。
问题已解决 - 我是个白痴...我猜... 感谢所有患者,尤其是 Hynek -Pichi- Vychodil! 我准备了我的测试代码来显示问题,我可以事实上重现了这个问题。然后我简化了代码以提高可读性,问题就消失了。我无法再次重现该问题。这对我来说既尴尬又神秘,因为我有这个问题好几天了。此外,mnesia 从未抱怨我在事务之外执行操作,并且我的代码中没有任何脏事务,我不知道我是如何将这个错误引入我的代码中的!
我已经将隔离的概念牢牢地印在了我的脑海中,并且不会怀疑它再次存在。
感谢您的教育。
实际上,问题在于在事务内 中使用try/catch 来处理mnesia 操作。请参阅here 了解更多信息。
【问题讨论】:
-
一个 mnesia 事务应该这样做。有什么不适合你的理由吗?
-
因为如果我有一个包含 10 个要迭代的键的列表,事务系统可以在我迭代时锁定第一条记录,然后锁定第二条,但有人可以更改第 10 个键在此代码到达之前。从本质上讲,我需要一种方法来锁定组中我试图以原子方式更改的所有记录。