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}]
网友评论