mneia數(shù)據(jù)庫時(shí)erlang自帶的一個(gè)nosql數(shù)據(jù)庫邓嘹,對(duì)其讀响驴、寫、刪除操作均有臟讀和非臟讀兩種性誉,之前存在一個(gè)誤區(qū)就是臟讀和非臟讀操作都支持transaction,在進(jìn)行代碼測(cè)試的時(shí)候出現(xiàn)和事物特性不一致的情況茎杂。
問題背景描述:
項(xiàng)目投產(chǎn)后错览,日常運(yùn)行中會(huì)產(chǎn)生大量的數(shù)據(jù),當(dāng)數(shù)據(jù)量不斷增加煌往,所占的內(nèi)存空間就會(huì)越大倾哺,對(duì)讀寫操作效率會(huì)有影響,而對(duì)于幾個(gè)月前的數(shù)據(jù)項(xiàng)目實(shí)際的運(yùn)行中基本用不到,但又不能將其直接刪除羞海,考慮將其遷移到一個(gè)備份表中闲勺,并將主表中的數(shù)據(jù)將其刪除】勖ǎ考慮到數(shù)據(jù)的安全性:將備份表的寫操作和主表的刪除操作,放入到事物中翘地,要么都成功申尤,要么都是失敗。同時(shí)為了保證項(xiàng)目性能衙耕,減少備份的時(shí)候昧穿,對(duì)數(shù)據(jù)庫的壓力,在進(jìn)行讀寫橙喘、刪除的時(shí)候采用diry的方式时鸵,在測(cè)試的時(shí)候發(fā)現(xiàn),dirty操作厅瞎,雖然加入到了事物饰潜,但是并不具事物的特性:同時(shí)成功同時(shí)失敗。
測(cè)試代碼
-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 %在事物里制造問題和簸,驗(yàn)證事物的有效性
end,
mnesia:transaction(F).
驗(yàn)證測(cè)試流程
-
初始化操作
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測(cè)試流程:最總無法刪除數(shù)據(jù)里的數(shù)據(jù)
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測(cè)試流程:apple的記錄將會(huì)被刪除
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測(cè)試流程:{shop, potato, 2456, 1.2}不能寫入數(shù)據(jù)庫
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測(cè)試流程:{shop, potato, 2456, 1.2}可以寫入數(shù)據(jù)庫
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}]