non-consistent multi-thread data

32 views
Skip to first unread message

vitya tsoi

unread,
Apr 9, 2016, 11:09:15 AM4/9/16
to Sophia database
non-consistent data on three or more threads. 

result of code exmple is

MISS: 300
TOTAL: 279

why?


 
char const* dbpath = "/tmp/sophia";


void* env = sp_env();
sp_setstring
(env, "sophia.path", dbpath, 0);
sp_setstring
(env, "db", "test", 0);
void* db = sp_getobject(env, "db.test");
sp_open
(env);
 
int id = 1;
int NREPEAT = 100;
int NTHR = 3;
 

auto lexec = [&](int idx) {
 

 
for (int i = 0; i < NREPEAT; ++i) {
   
int rc = 0;
   
   
do {

     
void *tx = sp_begin(env);
     
void *o = sp_document(db);
     sp_setstring
(o, "key", &id, sizeof(id));

     
int v = 0;

     
if ((o = sp_get(tx, o))) {
        v
= *(int*)sp_getstring(o, "value", nullptr);
        sp_destroy
(o);
     
}

     v
++;
 
     o
= sp_document(db);
     sp_setstring
(o, "key", &id, sizeof(id));
     sp_setstring
(o, "value", &v, sizeof(v));
     sp_set
(tx, o);
 

     
// on lock
     
// do rc = sp_commit(tx); while (2 == rc);

     
// or ignore lock
     rc
= sp_commit(tx);
     
if (2 == rc) sp_destroy(tx);
 

     
if (rc < 0) {
       
char* err = (char*)sp_getstring(env, "sophia.error", nullptr);
       fprintf
(stderr, "err: %s", err);
       free
(err);
       
exit(1);
     
}

   
} while (rc);

 
} // repeat

 
};
 

 std
::thread th[NTHR];
 
 
for (int i = 0; i < NTHR; ++i) {
   th
= std::thread(lexec, i);
 
}
 
 
for (int i = 0; i < NTHR; ++i)
   th
[i].join();
 
 
void *o = sp_document(db);
 sp_setstring
(o, "key", &id, sizeof(id));

 
int v = 0;
 
if ((o = sp_get(db, o)))
   v
= *(int*)sp_getstring(o, "value", nullptr);

 sp_destroy
(o);
 sp_destroy
(db);
 sp_destroy
(env);
 

 printf
("MISS %d", NTHR * NREPEAT);
 printf
("TOTAL %d", v);
 
assert((NTHR * NREPEAT) == v);
}
 

Dmitry Simonenko

unread,
Apr 9, 2016, 2:17:37 PM4/9/16
to Sophia database
I've made a mistake in the prepare logic of the commit. Sorry for that.

vitya tsoi

unread,
Apr 9, 2016, 7:34:06 PM4/9/16
to Sophia database
Excellent! Thank you!

what about case on lock


 do rc = sp_commit(tx); while (2 == rc);

commit return 1 if parallel  locker transaction is commited (data changed) and 0 if escaped?


суббота, 9 апреля 2016 г., 21:17:37 UTC+3 пользователь Dmitry Simonenko написал:

Dmitry Simonenko

unread,
Apr 10, 2016, 4:22:35 AM4/10/16
to Sophia database
Ok, the idea behind commit status is following:

status = sp_commit(tx)

(0) transaction commited:
all data has been successfully written to the storage.
the transaction is no longer exists.

(1) transaction forced to rollback on commit:
conflicting data has been changed by other commited transaction.
the transaction is no longer exists.

(2) in-lock
the transaction is in conflict by some other active transaction.
the transaction is exists.

Basically this status means that sp_commit(tx) should be retried later. In case if the conflicting transaction
(or all of them) are aborted for some reason, then transaction yet has a chance for 
successfull commit.

Following status can be used to implement an appllication specifics timeout,
resolve deadlocks, etc.

(-1) transaction forced to rollback on error
disk error, out-of-memory, etc.
the transaction is no longer exists.
Reply all
Reply to author
Forward
0 new messages