aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
authorDaniil Fedotov <[email protected]>2018-06-29 14:54:32 -0400
committerDaniil Fedotov <[email protected]>2018-07-03 09:23:53 -0400
commite052249e6ce4da0c6a022bb8da0186cd678e1054 (patch)
tree50fd509a34ab5e8ea9bc5b10b07f315833d786ad /lib/mnesia
parentd876b9a69fda446bf9d810cca82629ccbd17bf5f (diff)
downloadotp-e052249e6ce4da0c6a022bb8da0186cd678e1054.tar.gz
otp-e052249e6ce4da0c6a022bb8da0186cd678e1054.tar.bz2
otp-e052249e6ce4da0c6a022bb8da0186cd678e1054.zip
Fix delete_object and write convergence in transaction.
Fix a bug, when delete_object was deleting the record if it was written in the same transaction even if it was written to a different value. To verify: %% Create a set table mnesia:create_table(foo, []). %% Write and delete_object in transaction mnesia:transaction(fun() -> mnesia:write({foo, bar, one}), mnesia:delete_object({foo, bar, not_one}) end). {atomic, [{foo, bar, one}]} = mnesia:transaction(fun() -> mnesia:read(foo, bar) end). Added a section to isolation tests to check for non-matching delete_object requests.
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/src/mnesia.erl16
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl11
2 files changed, 20 insertions, 7 deletions
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index e298904e2a..df3a2dfe6f 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -779,12 +779,16 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) ->
?ets_insert(Store, {Oid, Val, delete_object});
_ ->
case ?ets_match_object(Store, {Oid, '_', write}) of
- [] ->
- ?ets_match_delete(Store, {Oid, Val, '_'}),
- ?ets_insert(Store, {Oid, Val, delete_object});
- _ ->
- ?ets_delete(Store, Oid),
- ?ets_insert(Store, {Oid, Oid, delete})
+ [] ->
+ ?ets_match_delete(Store, {Oid, Val, '_'}),
+ ?ets_insert(Store, {Oid, Val, delete_object});
+ Ops ->
+ case lists:member({Oid, Val, write}, Ops) of
+ true ->
+ ?ets_delete(Store, Oid),
+ ?ets_insert(Store, {Oid, Oid, delete});
+ false -> ok
+ end
end
end,
ok;
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index b2eea2390b..49bcec14af 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1563,7 +1563,8 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
?match({atomic, ok}, mnesia:create_table([{name, Tab},
{ram_copies, [Node1]}])),
ValPos = 3,
- RecA = {Tab, a, 1},
+ RecA = {Tab, a, 1},
+ RecA2 = {Tab, a, 2},
PatA = {Tab, '$1', 1},
RecB = {Tab, b, 3},
PatB = {Tab, '$1', 3},
@@ -1598,6 +1599,14 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
?match([], mnesia:index_read(Tab, 3, ValPos)),
%% delete_object
+ ?match(ok, mnesia:delete_object(RecA2)),
+ ?match([RecA], mnesia:read({Tab, a})),
+ ?match([RecA], mnesia:wread({Tab, a})),
+ ?match([RecA], mnesia:match_object(PatA)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA], mnesia:index_match_object(PatA, ValPos)),
+ ?match([RecA], mnesia:index_read(Tab, 1, ValPos)),
+
?match(ok, mnesia:delete_object(RecA)),
?match([], mnesia:read({Tab, a})),
?match([], mnesia:wread({Tab, a})),