我在mnesia中有一个表,我需要更新其中记录中的单个字段。据Erlang : Mnesia : Updating a single field value in a row,如果我这样做:Erlang:Mnesia:查询并更新基于密钥以外的字段
update_a(Tab, Key, Value) ->
fun() ->
[P] = mnesia:wread({Tab, Key}),
mnesia:write(Tab, P#rec{a=Value}, write)
end.
现在我明白了,上面的代码读取根据Key
记录P
,获取关于记录写锁定,这样就没有其他事务修改该记录,而正在读取和写回(或简而言之,已更新)。到现在为止还挺好。
现在我的要求是我需要能够根据Key
和表中的其他字段读取记录,然后对其执行更新。一个能够查找的函数是mnesia:match_object
。现在的问题是,根据http://www.erlang.org/doc/man/mnesia.html#match_object-3,该函数仅支持读取锁定,而不支持写入锁定。
这样做的后果是,假设在上面的功能我是用函数mnesia:match_object,我会得到一个(组)结果,所有的读锁。在阅读记录之后,我需要对检索到的数据执行一些检查,然后只有在条件满足时才写回更新的记录。现在,假设有两个并行事务T1和T2由两个不同的源运行。 T1和T2同时访问相同的记录。由于它们被读取锁定,因此T1和T2将能够并行读取记录。 T1和T2都将对同一条记录执行相同的检查,如果条件匹配,两者都将继续执行更新。但是,在我的代码中,如果T1和T2是连续执行的,则T1将对记录进行更改,并且在T2中,它将读取这些更改的记录,并且条件将失败并且不会进行更新。
总之,我需要写mnesia:match_object返回的锁定记录。文档明确指出只支持读锁。有什么替代品吗?
更新: 我一直在尝试一点点,并且我认为可能的解决方案是使用复合键。假设我有写像一个表中的数据:
mnesia:transaction(fun() -> mnesia:write(mytable, #rec{i={1,2}, a=2, b=3}, write) end).
有什么办法来查找条目,用不用管它?
我尝试了这些,但都返回空的结果:
mnesia:transaction(fun()-> mnesia:read(mytable, {1,'_'}, read) end).
mnesia:transaction(fun()-> mnesia:read(mytable, {1,_}, read) end).
这对我很有意义,谢谢! – ErJab 2009-12-03 06:11:01