4 Replies Latest reply: Aug 15, 2014 3:08 AM by 2731958 RSS

    Berkeley DB's Snapshot Isolation

    2731958

      After read the reference document, I think snapshot isolation means that a write operation will take a read lock in the data page under a transation. After that another transaction with read operation can read the page.But I code it like this:

       

      step1:txn1 update the page but not commited

      step2:txn2 read the page

      step3:commit txn1

      step4:commit txn2

       

      The program is stop in step2 and wait forever.Then I change step1 for read, It can excete normally.That's seems like the snapshot isolation is still take a wirte lock int the page.I feel confuss about how snapshot isolation works.

       

      If someone can give me an example program , or tell me how it works , I will thank you quit a lot.

        • 1. Re: Berkeley DB's Snapshot Isolation
          userBDBDMS-Oracle

          most likely you are not setting it up correctly.

           

          Please look in our programmers reference guide page 173 for more details on proper set up.

           

          http://docs.oracle.com/cd/E17076_04/html/programmer_reference/BDB_Prog_Reference.pdf

           

          thanks

          mike

          • 2. Re: Berkeley DB's Snapshot Isolation
            2731958

            Hi,mike,thanks for you answer.I read the document again and again today.According to the suggestion,we usually use snapshot in a read-only transaction and another update transation to write. So I recode my program with a read-only transaction and a update transaction.But it is also blocked like before.I feel so confuse. I put my program here and wish you can help me with that. thanks for your time.

             

            #include"db_cxx.h"

            #include<iostream>

            #include<cstring>

             

             

            int main()

            {

              u_int32_t env_flags =     DB_CREATE |

                                                 DB_INIT_LOCK |

                                                 DB_INIT_LOG |

                                                 DB_INIT_MPOOL |

                                                 DB_INIT_TXN;

              const char* home = "envHome";

             

              u_int32_t db_flags = DB_CREATE | DB_AUTO_COMMIT;

              const char* fileName = "envtest.db";

              Db* dbp = NULL;

             

              DbEnv myEnv(0);

             

              try{

                   myEnv.open(home,env_flags,0);

                   myEnv.set_flags(DB_MULTIVERSION,1);

             

                   dbp = new Db(&myEnv,0);

                   dbp->open(

                                       NULL,           //Txn pointer

                                       fileName,      //File name

                                       NULL,           //Logic db name

                                       DB_BTREE, //Database type

                                       db_flags,      //Open flags

                                       0                //file mode

                   );

              }catch(DbException &e){

                   std::cerr<<"Error when opening database and Environment:"

                                  <<fileName<<","<<home<<std::endl;

                   std::cerr<<e.what()<<std::endl;

              }

             

             

              //put data normally

              char *key1 = "luffy";

              char *data1 = "op";

              char *key2= "usopp";

              char *data2 = "brave";

             

             

              Dbt pkey1(key1,strlen(key1)+1);

              Dbt pdata1(data1,strlen(data1)+1);

              Dbt pkey2(key2,strlen(key2)+1);

              Dbt pdata2(data2,strlen(data2)+1);

             

             

              dbp->put(NULL,&pkey1,&pdata1,0);

              dbp->put(NULL,&pkey2,&pdata2,0);

             

             

              //using txn cursor to read and another cursor to modify before commit

              try{

             

                   DbTxn *txn1 = NULL;

                   myEnv.txn_begin(NULL,&txn1,DB_SNAPSHOT);

                   Dbc *cursorp = NULL;

                   dbp->cursor(txn1,&cursorp,0);

                   Dbt tempData1,tempKey2,tempData2;

                   tempData2.set_flags(DB_DBT_MALLOC);

                   cursorp->get(&pkey1,&tempData1,DB_SET);

                   cursorp->get(&tempKey2,&tempData2,DB_NEXT);

                   //cout just to see if it is right

                   std::cout<<(char*)pkey1.get_data()<<" : "<<(char*)tempData1.get_data()<<std::endl

                                      <<(char*)tempKey2.get_data()<<" : "<<(char*)tempData2.get_data()<<std::endl;

             

                   //txn2 to modify

                   DbTxn *txn2 = NULL;

                   myEnv.txn_begin(NULL,&txn2,0);

                   Dbc *temcur = NULL;

                   dbp->cursor(txn2,&temcur,0);

                   temcur->put(&pkey1,&pdata2,DB_KEYFIRST);          //the program will stop here and wait forever. if the snapshop isolation made a copy before , why still block here?

                                                                                                 //without this line,there won't deadlock.that means page was put a write lock before

                   //commit the txn

                   txn1->commit(0);

                   txn2->commit(0);

              }catch(DbException &e){

                  std::cerr<<"Error when use a txn"<<std::endl;

              }


              try{

                   dbp->close(0); //dbp should close before environment

                   myEnv.close(0);

              }catch(DbException &e){

                   std::cerr<<"Error when closing database and environment:"

                                            <<fileName<<","<<home<<std::endl;

                   std::cerr<<e.what()<<std::endl;

              }

             

              return 0;

            }

            • 3. Re: Berkeley DB's Snapshot Isolation
              userBDBDMS-Oracle

              Sometimes the cause of the problems is incorrect spelling of flag values.  Please ensure all your flag values are spelled correctly as specified in the docs. In the docs, we cover the correct spelling and usage of the flag values for each API. 

               

              thanks

              mike

              • 4. Re: Berkeley DB's Snapshot Isolation
                2731958

                Hi,mike, Thank you a lot. I surely made a mistake by using the wrong "DB_SNAPSHOT" flag.that should be "DB_TXN_SNAPSHOT". Now that program can running normally and I understand the snapshot ioslation.

                 

                Thanks again.

                zj