I'm not a mnesia expert, but i THINK the race condition is in the test not mnesia. transaction is still being committed and logged, when the dirty read is issued. if you add a sleep in between or better if you use mnesia:sync_transaction (<meta charset="utf-8"><a href="http://www.erlang.org/doc/man/mnesia.html#sync_transaction-3">http://www.erlang.org/doc/man/mnesia.html#sync_transaction-3</a>) instead of mnesia:transaction, the test will fail, i.e the case disappear<div>
isn't that the expected behavior or am i missing something?<br><div><div><meta charset="utf-8"><font class="Apple-style-span" face="Verdana, Arial, Helvetica, sans-serif"><br></font><br><div class="gmail_quote">On Tue, May 17, 2011 at 6:57 PM, John Hughes <span dir="ltr"><<a href="mailto:john.hughes@quviq.com">john.hughes@quviq.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">





<div bgcolor="#ffffff">
<div><font size="2" face="Arial">QuickCheck turned up another case of odd behaviour 
at Klarna.</font></div>
<div><font size="2" face="Arial"></font> </div>
<div><font size="2" face="Arial">The test runs mnesia on two nodes, creates a table 
on the OTHER node, then adds and deletes a record. After this the record is 
indeed not IN the table, but dirty_next finds its key anyway! Surely it 
shouldn't?</font></div>
<div><font size="2" face="Arial"></font> </div>
<div><font size="2" face="Arial">Here's the test:</font></div>
<div><font size="2" face="Arial"></font> </div>
<div><font size="2" face="Arial">test() -><br>    Slave = 
start_mnesia_with_slave(),<br>    {atomic,ok} = 
mnesia:create_table(rec,[{type,set},<br>        
{disc_only_copies,[Slave]}]),<br>    
ok          = 
mnesia:dirty_write({rec,4,1}),<br>    %% The next command MUST be 
done in a transaction, otherwise dirty_next works<br>    
{atomic,ok} = mnesia:transaction(fun()->mnesia:delete_object({rec,4,1}) 
end),<br>    %% Here's the problem: dirty_next returns 4, but 
this key is not in the table!<br>    
4           = 
mnesia:dirty_next(rec,0),<br>    
[]          = 
mnesia:dirty_read(rec,4).<br></font></div>
<div><font size="2" face="Arial">I'm starting mnesia and the slave node like 
this:</font></div>
<div><font size="2" face="Arial"></font> </div>
<div><font size="2" face="Arial">start_mnesia_with_slave() 
-><br>    {ok,Dir} = file:get_cwd(),<br>    ok 
= error_logger:tty(false),<br>    
mnesia:stop(),<br>    ok = 
error_logger:tty(true),<br>    
delete_file("mnesia"),<br>    
delete_file("slave"),<br>    ok = 
file:make_dir("mnesia"),<br>    ok = 
file:make_dir("slave"),<br>    Slave = 
slave(),<br>    ok = 
application:set_env(mnesia,dir,Dir++"/mnesia"),<br>    ok = 
rpc:call(Slave,application,set_env,[mnesia,dir,Dir++"/slave"]),<br>    
ok = mnesia:create_schema([node(),Slave]),<br>    ok = 
mnesia:start(),<br>    ok = 
rpc:call(Slave,mnesia,start,[]),<br>    Slave.</font></div>
<div> </div>
<div><font size="2" face="Arial">slave() -><br>    case 
slave:start_link(net_adm:localhost(),"slave") of<br> {ok,Slave} 
-><br>     
Slave;<br> {error,{already_running,Slave}} 
-><br>     Slave<br>    
end.<br></font></div>
<div><font size="2" face="Arial">I also have code to delete a file or directory, 
easy on Linux, darn difficult on Windows. You don't need this really, just run 
the test in an empty directory.</font></div>
<div><font size="2" face="Arial"></font> </div>
<div><font size="2" face="Arial">delete_file(Name) -><br>    case 
filelib:is_dir(Name) of<br> true -><br>     
[delete_file(Name++"/"++X) || X <- 
list_dir(Name)],<br>     
file:del_dir(Name),<br>     
delete_file(Name);<br> {error,eaccess} -><br>     
delete_file(Name);<br> {error,enoent} -><br>     
io:format("Could not find ~p\n",[Name]),<br>     
ok;<br> false -><br>     case file:delete(Name) 
of<br>  {error,enoent} -><br>      
ok;<br>  {error,eacces} -><br>      
io:format("Could not access ~p\n",[Name]),<br>      
delete_file(Name);<br>  ok -><br>      
delete_file(Name)<br>     end<br>    
end.</font></div>
<div> </div>
<div><font size="2" face="Arial">list_dir(Name) -><br>    case 
file:list_dir(Name) of<br> {ok,Files} -><br>     
Files;<br> {error,eacces} -><br>     
io:format("Could not list directory ~p\n",[Name]),<br>     
list_dir(Name);<br> {error,enoent} -><br>     
io:format("Could not find directory ~p\n",[Name]),<br>     
[]     <br>    end.<br></font></div><font color="#888888">
<div><font size="2" face="Arial">John</font></div></font></div>
<br>_______________________________________________<br>
erlang-bugs mailing list<br>
<a href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-bugs" target="_blank">http://erlang.org/mailman/listinfo/erlang-bugs</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Best Regards,<br>- Ahmed Omar<div><a href="http://nl.linkedin.com/in/adiaa" target="_blank">http://nl.linkedin.com/in/adiaa</a></div><div>Follow me on twitter</div><div>
<a href="http://twitter.com/#!/spawn_think" target="_blank">@spawn_think</a></div><br>
</div></div></div>