提交 d1808d72 authored 作者: Andrei Tokar's avatar Andrei Tokar

LockDecisionMakers adustments to match TxDecisionMaker logic for leftover map entry

上级 01977633
...@@ -18,7 +18,7 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue ...@@ -18,7 +18,7 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
final Object value; final Object value;
private final Transaction transaction; private final Transaction transaction;
long undoKey; long undoKey;
private long lastOperationId; protected long lastOperationId;
private Transaction blockingTransaction; private Transaction blockingTransaction;
private MVMap.Decision decision; private MVMap.Decision decision;
...@@ -54,16 +54,18 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue ...@@ -54,16 +54,18 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
// should wait on blockingTransaction that was determined earlier // should wait on blockingTransaction that was determined earlier
decision = MVMap.Decision.ABORT; decision = MVMap.Decision.ABORT;
} else if(id == lastOperationId) { } else if(id == lastOperationId) {
// There is no transaction with that id, so we've retried it just before, // There is no transaction with that id, and we've tried it just before,
// but map root has not changed (which must be the case if we just missed a closed transaction), // but map root has not changed (which must be the case if we just missed a closed transaction),
// therefore we came back here again. // therefore we came back here again.
// Now we assume it's a leftover after unclean shutdown (map update was written but not undo log), // Now we assume it's a leftover after unclean shutdown (map update was written but not undo log),
// and will effectively roll it back (just overwrite). // and will effectively roll it back (just assume committed value and overwrite).
Object committedValue = existingValue.getCommittedValue(); Object committedValue = existingValue.getCommittedValue();
logIt(committedValue == null ? null : VersionedValue.getInstance(committedValue)); logIt(committedValue == null ? null : VersionedValue.getInstance(committedValue));
decision = MVMap.Decision.PUT; decision = MVMap.Decision.PUT;
} else { } else {
// condition above means transaction has been committed/rolled back and closed by now // transaction has been committed/rolled back and is closed by now, so
// we can retry immediately and either that entry become committed
// or we'll hit case above
decision = MVMap.Decision.REPEAT; decision = MVMap.Decision.REPEAT;
lastOperationId = id; lastOperationId = id;
} }
...@@ -162,15 +164,28 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue ...@@ -162,15 +164,28 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
// and therefore will be committed soon // and therefore will be committed soon
logIt(null); logIt(null);
return setDecision(MVMap.Decision.PUT); return setDecision(MVMap.Decision.PUT);
} else if(fetchTransaction(blockingId) == null) { } else if(fetchTransaction(blockingId) != null) {
// map already has specified key from uncommitted // this entry comes from a different transaction, and this transaction is not committed yet
// at the time transaction, which is closed by now // should wait on blockingTransaction that was determined earlier and then try again
// we can retry right away
return setDecision(MVMap.Decision.REPEAT);
} else {
// map already has specified key from uncommitted transaction
// we need to wait for it to close and then try again
return setDecision(MVMap.Decision.ABORT); return setDecision(MVMap.Decision.ABORT);
} else if(id == lastOperationId) {
// There is no transaction with that id, and we've tried it just before,
// but map root has not changed (which must be the case if we just missed a closed transaction),
// therefore we came back here again.
// Now we assume it's a leftover after unclean shutdown (map update was written but not undo log),
// and will effectively roll it back (just assume committed value and overwrite).
Object committedValue = existingValue.getCommittedValue();
if(committedValue != null) {
return setDecision(MVMap.Decision.ABORT);
}
logIt(null);
return setDecision(MVMap.Decision.PUT);
} else {
// transaction has been committed/rolled back and is closed by now, so
// we can retry immediately and either that entry become committed
// or we'll hit case above
lastOperationId = id;
return setDecision(MVMap.Decision.REPEAT);
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论