From: <di...@us...> - 2012-09-12 05:26:44
|
Revision: 57136 http://firebird.svn.sourceforge.net/firebird/?rev=57136&view=rev Author: dimitr Date: 2012-09-12 05:26:38 +0000 (Wed, 12 Sep 2012) Log Message: ----------- Fixed CORE-3924: Bugcheck 291 (cannot find record back version) if GTT is modified concurrently using at least one read-committed read-only transaction. Modified Paths: -------------- firebird/trunk/src/jrd/vio.cpp Modified: firebird/trunk/src/jrd/vio.cpp =================================================================== --- firebird/trunk/src/jrd/vio.cpp 2012-09-12 03:44:56 UTC (rev 57135) +++ firebird/trunk/src/jrd/vio.cpp 2012-09-12 05:26:38 UTC (rev 57136) @@ -2125,6 +2125,7 @@ if (!(rpb->rpb_flags & rpb_gc_active)) { state = TRA_wait(tdbb, transaction, rpb->rpb_transaction_nr, jrd_tra::tra_wait); + if (state == tra_precommitted) state = check_precommitted(transaction, rpb); } @@ -2148,7 +2149,6 @@ // removed the records it modified and marked itself // committed - if (!DPM_get(tdbb, rpb, LCK_read)) { return false; } @@ -2157,7 +2157,6 @@ // we are reading is another record (newly inserted), // loop back and try again. - if (tid_fetch != rpb->rpb_transaction_nr) { CCH_RELEASE(tdbb, &rpb->getWindow(tdbb)); @@ -2213,8 +2212,12 @@ VIO_backout(tdbb, rpb, transaction); break; + case tra_limbo: + BUGCHECK(184); // limbo impossible + break; + default: - BUGCHECK(184); // limbo impossible + fb_assert(false); } } @@ -5137,11 +5140,11 @@ /* * The case statement for tra_us has been pushed down to this - * current position as we donot want to give update conflict + * current position as we do not want to give update conflict * errors and the "cannot update erased record" within the same - * transaction. We were getting these erroe in case of triggers. + * transaction. We were getting these errors in case of triggers. * A pre-delete trigger could update or delete a record which we - * are then tring to change. + * are then trying to change. * In order to remove these changes and restore original behaviour, * move this case statement above the 2 "if" statements. * smistry 23-Aug-99 @@ -5207,8 +5210,12 @@ // backout a fragmented dead record version, spin wait because it will // finish shortly. - if (!(rpb->rpb_flags & rpb_gc_active)) { + if (!(rpb->rpb_flags & rpb_gc_active)) + { state = TRA_wait(tdbb, transaction, rpb->rpb_transaction_nr, jrd_tra::tra_wait); + + if (state == tra_precommitted) + state = check_precommitted(transaction, rpb); } else { @@ -5231,6 +5238,7 @@ update_conflict_trans = rpb->rpb_transaction_nr; continue; } + if (state != tra_dead && !(temp->rpb_flags & rpb_deleted)) { if (!DPM_fetch(tdbb, temp, LCK_write)) { @@ -5238,6 +5246,7 @@ } delete_record(tdbb, temp, 0, 0); } + switch (state) { case tra_committed: @@ -5257,6 +5266,10 @@ case tra_dead: break; + + default: + fb_assert(false); + } // switch (state) break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |