Changeset: 92fece8ebda9 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=92fece8ebda9
Modified Files:
        sql/storage/store.c
        sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
Branch: 2PC
Log Message:

keep a 'inflight' precommit_id in the global transaction. This
is the only precommit which can continue. And during that
phase no other transactions can start a precommit.


diffs (87 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3157,6 +3157,22 @@ rollforward_trans(sql_trans *tr, int mod
        return ok;
 }
 
+/* 2PC
+ * Concurrent precommit's can currently not be handled. This because we use
+ * the per column, table, schema, transaction timestamps for the apply (in 
memory 
+ * update of all structures including the BATS). Therefor we now have a global
+ * flag indicating that a pre-commit has happend and we are waiting until
+ * the persistcommit. 
+ *
+ * Improvements over this (too) simple scheme are
+ *     1) Add a timeout after which we will again failback to allowing new
+ *     pre-commits etc. Problem is we cannot ever apply the pending pre-commit.
+ *
+ *     2) Have a list of in-flight precommits, each with a non overlapping
+ *     set of updated tables. This would (at least) allow for concurrent
+ *     different table updates and inserts.
+ * 2PC
+ */
 static int
 validate_tables(sql_schema *s, sql_schema *os)
 {
@@ -3475,8 +3491,11 @@ sql_trans_validate(sql_trans *tr)
 {
        node *n;
 
+       /* We cannot handle other outstanding precommits */
+       if (tr->parent == gtrans && gtrans->precommit_id)
+               return 0;
+
        /* depends on the iso level */
-
        if (tr->schema_number != store_schema_number())
                return 0;
 
@@ -3574,6 +3593,8 @@ sql_trans_precommit(sql_trans *tr)
                if (result == LOG_OK)
                        result = logger_funcs.log_tend();
                tr->schema_number = store_schema_number();
+               /* Mark current precommit in flight */
+               gtrans->precommit_id = tr->precommit_id;
                return (result==LOG_OK)?SQL_OK:SQL_ERR;
        }
        return (result==LOG_OK)?SQL_OK:SQL_ERR;
@@ -3595,8 +3616,10 @@ sql_trans_persistcommit(sql_trans *tr)
        if (result == LOG_OK) {
                /* Mark the transaction as globally persisted as well */
                result = logger_funcs.log_persist_precommit(tr->precommit_id);
+               assert(tr->precommit_id == gtrans->precommit_id);
+               gtrans->precommit_id = 0;
        }
-    return (result==LOG_OK)?SQL_OK:SQL_ERR;
+       return (result==LOG_OK)?SQL_OK:SQL_ERR;
 }
 
 int
diff --git a/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py 
b/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
--- a/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
+++ b/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
@@ -38,11 +38,20 @@ run(c2, 'INSERT INTO htmtest VALUES (5, 
 #run(c3, 'INSERT INTO htmtest VALUES (6, 60)')
 
 run(c2, 'CALL precommit(2)')
-run(c1, 'CALL precommit(1)')
+try:
+    run(c1, 'CALL precommit(1)')
+except:
+    print "precommit failed\n"
 #run(c3, 'CALL precommit(3)')
 
-run(c1, 'CALL persistcommit(1)')
+try:
+    run(c1, 'CALL persistcommit(1)')
+except:
+    print "persistcommit failed\n"
 run(c2, 'CALL persistcommit(2)')
 
-query(c1, 'SELECT * FROM htmtest')
+try:
+    query(c1, 'SELECT * FROM htmtest')
+except:
+    print "select fails on aborted transaction\n"
 query(c2, 'SELECT * FROM htmtest')
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to