Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 477361
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T00:34:59+00:00 2026-05-13T00:34:59+00:00

I have a table in mnesia and I need to update individual fields in

  • 0

I have a table in mnesia and I need to update individual fields in the records in it. According to Erlang : Mnesia : Updating a single field value in a row if I do something like:

update_a(Tab, Key, Value) ->
  fun() ->
    [P] = mnesia:wread({Tab, Key}),
    mnesia:write(Tab, P#rec{a=Value}, write)
  end.

Now as I understand, the above code reads a record P based on a Key, acquiring a write lock on the record, so that no other transactions modify this record while it is being read and written back (or in short, updated). So far so good.

Now my requirement is that I need to able to read records based on both the Key and one other field in the table and then perform an update on it. A function that will do this looking up is mnesia:match_object. The problem now is that, the function only supports a read lock, not a write lock, according to http://www.erlang.org/doc/man/mnesia.html#match_object-3.

The consequence of this is that, suppose in the above function I were to use mnesia:match_object, I will get a (group of) record(s), all with read locks. After I read the records, I need to perform some checks on the retrieved data and then write back the updated record only if a condition is satisfied. Now, assume there are two parallel transactions T1 and T2 initiated by two different sources running. Both T1 and T2 access the same record, at the same time. Since they are read locked, both T1 and T2 will be able to read the records parallely. Both T1 and T2 will perform the same check on the same record, and if the condition matches, both will proceed to execute the update. But, in my code, if T1 and T2 were to have executed serially, T1 would have made changes to the record and in T2, it would have read these changed records and the condition would have failed and no update would have been made.

In short, I need to write lock records that are returned by mnesia:match_object. The documentation clearly states only read lock is supported. Are there are any alternatives?

UPDATE:
I’ve been experimenting a little bit, and a possible solution I thought could be to use compound keys. Suppose I have data written to a table like:

mnesia:transaction(fun() -> mnesia:write(mytable, #rec{i={1,2}, a=2, b=3}, write) end).

Is there any way to lookup entries, using don’t cares?

I tried these, but both returned empty results:

mnesia:transaction(fun()-> mnesia:read(mytable, {1,'_'}, read) end).
mnesia:transaction(fun()-> mnesia:read(mytable, {1,_}, read) end).
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T00:35:00+00:00Added an answer on May 13, 2026 at 12:35 am

    You don’t have to worry about it. From the mnesia documentation:

    Read locks may be shared, which means that if one transaction manages to acquire a read lock on an item, other transactions may also acquire a read lock on the same item. However, if someone has a read lock no one can acquire a write lock at the same item. If some one has a write lock no one can acquire a read lock nor a write lock at the same item.

    If a transaction has a read lock on an object, that object can’t be edited by another transaction.

    Say you have two transactions, T1 and T2, which are executing in parallel:

    1. T1 does mnesia:match_object, and acquires a read lock on all the returned objects.
    2. T2 does an equivalent mnesia:match_object, and acquires a read lock on the same objects.
    3. T2 attempts to acquire a write lock on of the objects (to edit it).
    4. Mnesia automatically aborts T2, to be retried later.
    5. T1 acquires a write lock on the objects, and edits them.
    6. T1 finishes.
    7. Mnesia retries T2.

    Note that T2 may be retried several times, depending on how long T1 takes to complete (ie. release its locks).

    According to my tests, the locking behavior of mnesia:match_object isn’t consistent. For example, mnesia:match_object(mytable, {mytable, 2, '_'}, LockType) will lock only the record with Key 2, but mnesia:match_object(mytable, {mytable, '_', test}, LockType) locks the entire table.

    Also note that the documentation isn’t correct, mnesia:match_object(Table, Pattern, write) does work, and seems to follow the same pattern as ‘read’, ie. if you specify the key, only the matching record will be write-locked; if you don’t specify the key, the entire table will be write-locked.

    You can test it yourself by doing something like this:

    test() ->
        mnesia:transaction(fun()-> 
            Table = mytable,
            Matches = mnesia:match_object(Table, {Table, 2, '_'}, write),
            io:format("matched: ~p~n", [Matches]),
            spawn(fun()->mnesia:transaction(fun()->
                            io:format("trying to read~n",[]),
                            io:format("read: ~p~n", [mnesia:read(Table, 2, read)])
                            end) end),        
            timer:sleep(1000),
            RereadMatches = lists:map(fun(#mytable{id=Id}) -> mnesia:read(Table, Id, write) end, Matches),
            io:format("reread matches: ~p~n", [RereadMatches])
            end).
    

    By changing the pattern and lock type passed to match_object, and the key number and lock type passed to mnesia:read in the spawned process (or by using mnesia:write), you can test the various locking behaviors.

    Addendum: See this post by Ulf Wiger on the same topic.

    Addendum 2: See the section on “Isolation” in the Mnesia user guide.

    Edit: The above was all done on a set-type table, match_object locking behavior might be different on a bag-type table.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an mnesia table with fields say f1, f2, f3. Now if I
I have an mnesia table with three fields, i, a and b, created using
I have a mnesia table for this record. -record(peer, { peer_key, %% key is
I'm trying to build a small testing app with erlang+mnesia. I have a user
I have table inside a div tab. The table has 40 rows in it
I have table with 50 entries (users with such details like Name Surname Location
I have table rows of data in html being filled from a CGI application.
Imagine I have table like this: id:Product:shop_id 1:Basketball:41 2:Football:41 3:Rocket:45 4:Car:86 5:Plane:86 Now, this
While trying to use LINQ to SQL I encountered several problems. I have table
I have a table with more than a millon rows. This table is used

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.