|
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.
|