[erlang-questions] Accessing two versions of records when doing transform_table in mnesia

Hakan Mattsson hakan@REDACTED
Thu Jul 17 15:33:20 CEST 2008


On Thu, 17 Jul 2008, devdoer bird wrote:

db> 2008/7/17, Hakan Mattsson <hakan@REDACTED>:
db> >
db> > On Thu, 17 Jul 2008, devdoer bird wrote:
db> > db> My question is
db> > db> 1. while the upgrade is in in progress, is the user record I read
db> > db> either the version 1 or the version 2 ? That is I can't be sure
db> > db> one user record's current version.
db> > db> 2. while the upgrade is in progress,will the modify  of the old user
db> > db> record be lost?
db> >
db> > It will differ per module and process. During the upgrade you may have
db> > some processes that are using the old module and some are using the
db> > new module. If this is an issue, you need to perform a more advanced
db> > upgrade procedure that first suspends the processes, then loads the
db> > new code and finally resumes the processes.
db> 
db> I can't understand. Won't one process read either version 1 or version 2?
db> Eg. there're 5 user records of version 1 intially, when I do
db> transform_table,there may
db> be 3 user records of version 1,and 2 user records of version 2 if the
db> transform_table operation is not finished yet.

mnesia:transform_table/2 grabs a table lock. If you are using
transactions you need to wait for the transform to complete before you
can access the table.

If you are performing dirty access during the mnesia:transform_table/2
operation, reading of some records will result in version 1 and others
will result in version 2. Dirty updates may be overwritten by
mnesia:transform_table/2.

Then you have the issue of which version of your code that is
running. During the code upgrade, some processes will run version 1 of
a module (using version 1 of the record definition) while others will
run version 2 of the module (using version 2 of the record definition).

db> > db> 3. If the 1 and 2 are true,how can I  code two handle them? 
db> > db> Shall I have to have two versions of process code to handle 
db> > db> this situation ,like:
db> > db> process_one_user(UserRecord)->
db> > db>    case of current_version(UserRecord) of
db> > db>         v1-> do something;
db> > db>         v2->do  something
db> > db>      end
db> > db> end
db> >
db> > One way of getting better control of this, is to change the name
db> > of the record. Then it will be easy to test which "version" of
db> > the record that you are using. See also mnesia:transform_table/4.
db> 
db> If I do so,many codes rely on the original record name will be
db> changed, and I have to code in  if-else style in many place .
db> Am I right?

Yes. If the change affects too many modules, that approach is impractical.

An other way of handling it is to have wrapper functions for all
reading operations in Mnesia. If the wrapper detects a record with
version 1 it could transform it into version 2.

/Håkan
---
Håkan Mattsson (uabhams)
Erlang/OTP, Ericsson


More information about the erlang-questions mailing list