| Author |
Message |
< Advanced Erlang/OTP ~ Mnesia transaction inside an mnesia transaction etc... |
| Ludvig |
Posted: Mon Aug 07, 2006 7:45 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 38
Location: London
|
If you have a Mnesia transaction inside another mnesia transaction and the inner transaction fails, will the the databse do a full rollover on the whole transaction or just the inner transaction?? Or what will happen??
Example:
Code:
func1(Key) ->
Fun = fun() ->
Result = mensia:read({test,key}),
func2(Result),
mnesia:write({test2,["hi","ho"]})
end,
mnesia:transaction(Fun).
func2(Result) ->
Fun = fun() ->
mnesia:write({test2,Result})
end,
mnesia:transaction(Fun).
-------------------
Really bad intendention.. |
|
|
| Back to top |
|
| oscarh |
Posted: Wed Aug 23, 2006 12:55 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 22
|
If the inner transaction is aborted, only that one is affected.
Code:
-module(test).
-compile(export_all).
-record(test, {id, value}).
create_table() ->
mnesia:create_table(test, []).
transaction() ->
mnesia:transaction(fun() ->
mnesia:write(#test{id = 1, value = "test 1"}),
mnesia:write(#test{id = 2, value = "test 2"}),
transaction_2(),
mnesia:write(#test{id = 3, value = "test 3"})
end
).
transaction_2() ->
mnesia:transaction(fun()->
[Record] = mnesia:read(1),
mnesia:write(Record#test{id = 1, value = "updated test 1"}),
mnesia:abort(testing_abort)
end).
Code: Eshell V5.4.9 (abort with ^G)
1> application:start(mnesia).
ok
2> test:create_table().
{atomic,ok}
3> mnesia:dirty_all_keys(test).
[]
4> test:transaction().
{atomic,ok}
5> mnesia:dirty_all_keys(test).
[1,2,3]
You could check for the result of the inner one:
Code:
-module(test).
-compile(export_all).
-record(test, {id, value}).
create_table() ->
mnesia:create_table(test, []).
transaction() ->
mnesia:transaction(fun() ->
mnesia:write(#test{id = 1, value = "test 1"}),
mnesia:write(#test{id = 2, value = "test 2"}),
case transaction_2() of
{atomic, _Result} -> ok;
{aborted, _Reason} -> mnesia:abort(inner_aborted)
mnesia:write(#test{id = 3, value = "test 3"})
end
).
transaction_2() ->
mnesia:transaction(fun()->
[Record] = mnesia:read(1),
mnesia:write(Record#test{id = 1, value = "updated test 1"}),
mnesia:abort(testing_abort)
end).
Code: Eshell V5.4.9 (abort with ^G)
1> application:start(mnesia).
ok
2> test:create_table().
{atomic,ok}
3> mnesia:dirty_all_keys(test).
[]
4> test:transaction().
{aborted,inner_aborted}
5> mnesia:dirty_all_keys(test).
[]
|
|
|
| Back to top |
|
| Ludvig |
Posted: Wed Aug 23, 2006 1:05 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 38
Location: London
|
Thanks for trying to solve my problem. But your explanation gave me a new problem. In your code:
Code: -module(test).
-compile(export_all).
-record(test, {id, value}).
create_table() ->
mnesia:create_table(test, []).
transaction() ->
mnesia:transaction(fun() ->
mnesia:write(#test{id = 1, value = "test 1"}),
mnesia:write(#test{id = 2, value = "test 2"}),
case transaction_2() of
{atomic, _Result} -> ok;
{aborted, _Reason} -> mnesia:abort(inner_aborted)
end,
mnesia:write(#test{id = 3, value = "test 3"})
end
).
transaction_2() ->
mnesia:transaction(fun()->
[Record] = mnesia:read(1),
mnesia:write(Record#test{id = 1, value = "updated test 1"}),
mnesia:abort(testing_abort)
end).
I change it to this:
Code: -module(test).
-compile(export_all).
-record(test, {id, value}).
create_table() ->
mnesia:create_table(test, []).
transaction() ->
mnesia:transaction(fun() ->
mnesia:write(#test{id = 1, value = "test 1"}),
mnesia:write(#test{id = 2, value = "test 2"}),
case transaction_2() of
{atomic, _Result} -> ok;
{aborted, _Reason} -> mnesia:abort(inner_aborted)
end,
mnesia:write(#test{id = 3, value = "test 3"}),
mnesia:abort(problem_in_paradise)
end
).
transaction_2() ->
mnesia:transaction(fun()->
[Record] = mnesia:read(1),
mnesia:write(Record#test{id = 1, value = "updated test 1"}),
end).
As you can see I changed so that transaction_2 dosen't abort. But instead an aborted is done after transaction_2 is finished.
How will this affect the transactions and is there any way to abort the transaction_2 after it has been finished? |
|
|
| Back to top |
|
| oscarh |
Posted: Wed Aug 23, 2006 1:33 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 22
|
First of all, in the future I should try and post code that compiles.
However, the inner transaction is never really comitted before the outer one is:
Code:
-module(test).
-compile(export_all).
-record(test, {id, value}).
create_table() ->
mnesia:create_table(test, []).
transaction() ->
mnesia:transaction(fun() ->
mnesia:write(#test{id = 1, value = "test 1"}),
mnesia:write(#test{id = 2, value = "test 2"}),
case transaction_2() of
{atomic, _Result} -> ok;
{aborted, Reason} -> mnesia:abort({inner_aborted, Reason})
end,
mnesia:write(#test{id = 3, value = "test 3"}),
mnesia:abort(problem_in_paradise)
end
).
transaction_2() ->
mnesia:transaction(fun()->
[Record] = mnesia:read({test, 1}),
mnesia:write(Record#test{value = "updated test 1"}),
mnesia:write(#test{id = 4, value = "test 4"})
end).
Gives:
Code:
1> application:start(mnesia).
ok
2> test:create_table().
{atomic,ok}
3> mnesia:dirty_all_keys(test).
[]
4> test:transaction().
{aborted,problem_in_paradise}
5> mnesia:dirty_all_keys(test).
[]
|
|
|
| Back to top |
|
| oscarh |
Posted: Wed Aug 23, 2006 1:47 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 22
|
|
| Back to top |
|
| Ludvig |
Posted: Fri Aug 25, 2006 8:57 am |
|
|
|
User
Joined: 20 Jul 2006
Posts: 38
Location: London
|
Thank you!
There where some really god examples. Just what I needed. |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|