Commit f299e81c authored by Yoni Fogel's avatar Yoni Fogel

Addresses #1093

Nested transactions not done child first:
parent will still finish (abort) if the child has an error in committing or aborting.


git-svn-id: file:///svn/tokudb@5721 c7de825b-a66e-492c-adef-691d508d4ae1
parent fb16825e
...@@ -959,9 +959,12 @@ static int toku_txn_commit(DB_TXN * txn, u_int32_t flags) { ...@@ -959,9 +959,12 @@ static int toku_txn_commit(DB_TXN * txn, u_int32_t flags) {
if (!txn) return EINVAL; if (!txn) return EINVAL;
HANDLE_PANICKED_ENV(txn->mgrp); HANDLE_PANICKED_ENV(txn->mgrp);
//Recursively kill off children //Recursively kill off children
int r_child_first = 0;
while (txn->i->child) { while (txn->i->child) {
int r_child = toku_txn_commit(txn->i->child, flags); int r_child = toku_txn_commit(txn->i->child, flags);
assert(r_child==0); if (!r_child_first) r_child_first = r_child;
//In a panicked env, the child may not be removed from the list.
HANDLE_PANICKED_ENV(txn->mgrp);
} }
//Remove from parent //Remove from parent
if (txn->parent) { if (txn->parent) {
...@@ -977,23 +980,21 @@ static int toku_txn_commit(DB_TXN * txn, u_int32_t flags) { ...@@ -977,23 +980,21 @@ static int toku_txn_commit(DB_TXN * txn, u_int32_t flags) {
//toku_ydb_notef("flags=%d\n", flags); //toku_ydb_notef("flags=%d\n", flags);
int nosync = (flags & DB_TXN_NOSYNC)!=0; int nosync = (flags & DB_TXN_NOSYNC)!=0;
flags &= ~DB_TXN_NOSYNC; flags &= ~DB_TXN_NOSYNC;
if (flags!=0) {
//TODO: Release locks perhaps?
if (txn->i) {
if (txn->i->tokutxn)
toku_logger_abort(txn->i->tokutxn);
toku_free(txn->i);
}
toku_free(txn);
return EINVAL;
}
int r2 = toku_txn_release_locks(txn); int r2 = toku_txn_release_locks(txn);
int r = toku_logger_commit(txn->i->tokutxn, nosync); // frees the tokutxn int r;
if (r_child_first || flags!=0)
r = toku_logger_abort(txn->i->tokutxn); // frees the tokutxn
else
r = toku_logger_commit(txn->i->tokutxn, nosync); // frees the tokutxn
// the toxutxn is freed, and we must free the rest. */ // the toxutxn is freed, and we must free the rest. */
// The txn is no good after the commit even if the commit fails.
if (txn->i) if (txn->i)
toku_free(txn->i); toku_free(txn->i);
toku_free(txn); toku_free(txn);
return r2 ? r2 : r; // The txn is no good after the commit even if the commit fails. if (flags!=0) return EINVAL;
return r ? r : (r2 ? r2 : r_child_first);
} }
static u_int32_t toku_txn_id(DB_TXN * txn) { static u_int32_t toku_txn_id(DB_TXN * txn) {
...@@ -1006,9 +1007,12 @@ static u_int32_t toku_txn_id(DB_TXN * txn) { ...@@ -1006,9 +1007,12 @@ static u_int32_t toku_txn_id(DB_TXN * txn) {
static int toku_txn_abort(DB_TXN * txn) { static int toku_txn_abort(DB_TXN * txn) {
HANDLE_PANICKED_ENV(txn->mgrp); HANDLE_PANICKED_ENV(txn->mgrp);
//Recursively kill off children //Recursively kill off children
int r_child_first = 0;
while (txn->i->child) { while (txn->i->child) {
int r_child = toku_txn_abort(txn->i->child); int r_child = toku_txn_abort(txn->i->child);
assert(r_child==0); if (!r_child_first) r_child_first = r_child;
//In a panicked env, the child may not be removed from the list.
HANDLE_PANICKED_ENV(txn->mgrp);
} }
//Remove from parent //Remove from parent
if (txn->parent) { if (txn->parent) {
...@@ -1026,7 +1030,7 @@ static int toku_txn_abort(DB_TXN * txn) { ...@@ -1026,7 +1030,7 @@ static int toku_txn_abort(DB_TXN * txn) {
toku_free(txn->i); toku_free(txn->i);
toku_free(txn); toku_free(txn);
return r ? r : r2; return r ? r : (r2 ? r2 : r_child_first);
} }
static int toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags); static int toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment