美文网首页
erlang mnesia数据库事物应用

erlang mnesia数据库事物应用

作者: 司马阿Q | 来源:发表于2017-09-28 18:37 被阅读0次

    mneia数据库时erlang自带的一个nosql数据库,对其读、写、删除操作均有脏读和非脏读两种,之前存在一个误区就是脏读和非脏读操作都支持transaction,在进行代码测试的时候出现和事物特性不一致的情况。

    问题背景描述:

    项目投产后,日常运行中会产生大量的数据,当数据量不断增加,所占的内存空间就会越大,对读写操作效率会有影响,而对于几个月前的数据项目实际的运行中基本用不到,但又不能将其直接删除,考虑将其迁移到一个备份表中,并将主表中的数据将其删除。考虑到数据的安全性:将备份表的写操作和主表的删除操作,放入到事物中,要么都成功,要么都是失败。同时为了保证项目性能,减少备份的时候,对数据库的压力,在进行读写、删除的时候采用diry的方式,在测试的时候发现,dirty操作,虽然加入到了事物,但是并不具事物的特性:同时成功同时失败。

    测试代码

    -module(test_mnesia).
    -import(lists, [foreach/2]).
    -include_lib("stdlib/include/qlc.hrl").
    -compile(export_all).
    -record(shop, {item, quantity, cost}).
    
    do_this_once() ->
      mnesia:create_schema([node()]),
      mnesia:start(),
      mnesia:create_table(shop, [{attributes, record_info(fields, shop)}]),
      mnesia:stop().
    
    start() ->
      mnesia:stop(),
      mnesia:start(),
      mnesia:wait_for_tables([shop], 2000),
      init_table(shop_info()).
    
    get_all(TabelName) ->
      Qh =qlc:q([X || X <- mnesia:table(TabelName)]),
      F = fun() -> qlc:e(Qh) end,
      {atomic, Val} = mnesia:transaction(F),
      Val.
    
    shop_info() ->
      [%% The shop table
        {shop, apple, 20, 2.3},
        {shop, orange, 100, 3.8},
        {shop, pear, 200, 3.6},
        {shop, banana, 420, 4.5}
      ].
    init_table(TableData) ->
      F = fun(Model) -> mnesia:dirty_write(Model) end,
      lists:foreach(F, TableData).
    
    delete(Item) ->
      Oid = {shop, Item},
      F = fun() ->
        mnesia:delete(Oid)
          end,
      mnesia:transaction(F).
    
    dirty_delete(Item) ->
      Oid = {shop, Item},
      F = fun() ->
        mnesia:dirty_delete(Oid)
          end,
      mnesia:transaction(F).
    
    write() ->
      Oid =  {shop, potato, 2456, 1.2},
      F = fun() ->
        mnesia:write(Oid)
          end,
      mnesia:transaction(F).
    
    dirty_write() ->
      Oid =  {shop, potato, 2456, 1.2},
      F = fun() ->
        mnesia:dirty_write(Oid)
          end,
      mnesia:transaction(F).
    
    execute(Function,Pram) when is_function(Function),is_list(Pram) ->
      F = fun() ->
        apply(Function,Pram)
        ,true = ok  %在事物里制造问题,验证事物的有效性
          end,
      mnesia:transaction(F).
    
    验证测试流程
    • 初始化操作
    1> c(test_mnesia).
    test_mnesia.erl:67: Warning: no clause will ever match
    {ok,test_mnesia}
    2> test_mnesia:do_this_once().
    stopped
    3>
    =INFO REPORT==== 28-Sep-2017::18:19:14 ===
        application: mnesia
        exited: stopped
        type: temporary
    
    3> test_mnesia:start().
    ok
    4>
    
    • delete测试流程:最总无法删除数据里的数据
    6>  test_mnesia:get_all(shop).                                               
    [{shop,apple,20,2.3},                                                        
     {shop,orange,100,3.8},                                                      
     {shop,pear,200,3.6},                                                        
     {shop,banana,420,4.5}]                                                      
    7> test_mnesia:execute(fun test_mnesia:delete/1,[apple]).                    
    {aborted,{{badmatch,ok},                                                     
              [{test_mnesia,'-execute/2-fun-0-',2,                               
                            [{file,"test_mnesia.erl"},{line,67}]},               
               {mnesia_tm,apply_fun,3,[{file,"mnesia_tm.erl"},{line,836}]},      
               {mnesia_tm,execute_transaction,5,                                 
                          [{file,"mnesia_tm.erl"},{line,811}]},                  
               {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},         
               {shell,exprs,7,[{file,"shell.erl"},{line,686}]},                  
               {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},             
               {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}            
    8> test_mnesia:get_all(shop).                                                
    [{shop,apple,20,2.3},                                                        
     {shop,orange,100,3.8},                                                      
     {shop,pear,200,3.6},                                                        
     {shop,banana,420,4.5}]                                                      
    
    • dirty_delete测试流程:apple的记录将会被删除
    8> test_mnesia:get_all(shop).
    [{shop,apple,20,2.3},
     {shop,orange,100,3.8},
     {shop,pear,200,3.6},
     {shop,banana,420,4.5}]
    9> test_mnesia:execute(fun test_mnesia:dirty_delete/1,[apple]).
    {aborted,{{badmatch,ok},
              [{test_mnesia,'-execute/2-fun-0-',2,
                            [{file,"test_mnesia.erl"},{line,67}]},
               {mnesia_tm,apply_fun,3,[{file,"mnesia_tm.erl"},{line,836}]},
               {mnesia_tm,execute_transaction,5,
                          [{file,"mnesia_tm.erl"},{line,811}]},
               {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
               {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
               {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
               {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}
    10> test_mnesia:get_all(shop).
    [{shop,orange,100,3.8},
     {shop,pear,200,3.6},
     {shop,banana,420,4.5}]
    
    • write测试流程:{shop, potato, 2456, 1.2}不能写入数据库
    10> test_mnesia:get_all(shop).                                                         
    [{shop,orange,100,3.8},                                                                
     {shop,pear,200,3.6},                                                                  
     {shop,banana,420,4.5}]                                                                
    11> test_mnesia:execute(fun test_mnesia:write/0,[]).                                   
    {aborted,{{badmatch,ok},                                                               
              [{test_mnesia,'-execute/2-fun-0-',2,                                         
                            [{file,"test_mnesia.erl"},{line,67}]},                         
               {mnesia_tm,apply_fun,3,[{file,"mnesia_tm.erl"},{line,836}]},                
               {mnesia_tm,execute_transaction,5,                                           
                          [{file,"mnesia_tm.erl"},{line,811}]},                            
               {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},                   
               {shell,exprs,7,[{file,"shell.erl"},{line,686}]},                            
               {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},                       
               {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}                      
    12>  test_mnesia:get_all(shop).                                                        
    [{shop,orange,100,3.8},                                                                
     {shop,pear,200,3.6},                                                                  
     {shop,banana,420,4.5}]                                                                
    
    • dirty_write测试流程:{shop, potato, 2456, 1.2}可以写入数据库
    12>  test_mnesia:get_all(shop).
    [{shop,orange,100,3.8},
     {shop,pear,200,3.6},
     {shop,banana,420,4.5}]
    13> test_mnesia:execute(fun test_mnesia:dirty_write/0,[]).
    {aborted,{{badmatch,ok},
              [{test_mnesia,'-execute/2-fun-0-',2,
                            [{file,"test_mnesia.erl"},{line,67}]},
               {mnesia_tm,apply_fun,3,[{file,"mnesia_tm.erl"},{line,836}]},
               {mnesia_tm,execute_transaction,5,
                          [{file,"mnesia_tm.erl"},{line,811}]},
               {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
               {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
               {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
               {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}
    14>  test_mnesia:get_all(shop).
    [{shop,potato,2456,1.2},
     {shop,orange,100,3.8},
     {shop,pear,200,3.6},
     {shop,banana,420,4.5}]
    

    总结:从上面的测试可以看出,mnesia数据库关于dirty的操作不支持事物。

    相关文章

      网友评论

          本文标题:erlang mnesia数据库事物应用

          本文链接:https://www.haomeiwen.com/subject/xfomextx.html