Unverified 提交 da2fcc08 authored 作者: Andrei Tokar's avatar Andrei Tokar 提交者: GitHub

Merge pull request #1520 from h2database/pit-if-absent

Fixes bug in PutIfAbsentDecisionMaker
...@@ -395,6 +395,7 @@ public class Transaction { ...@@ -395,6 +395,7 @@ public class Transaction {
try { try {
store.rollbackTo(this, logId, savepointId); store.rollbackTo(this, logId, savepointId);
} finally { } finally {
notifyAllWaitingTransactions();
long expectedState = composeState(STATUS_ROLLING_BACK, logId, hasRollback(lastState)); long expectedState = composeState(STATUS_ROLLING_BACK, logId, hasRollback(lastState));
long newState = composeState(STATUS_OPEN, savepointId, true); long newState = composeState(STATUS_OPEN, savepointId, true);
if (!statusAndLogId.compareAndSet(expectedState, newState)) { if (!statusAndLogId.compareAndSet(expectedState, newState)) {
...@@ -404,7 +405,6 @@ public class Transaction { ...@@ -404,7 +405,6 @@ public class Transaction {
"while rollback to savepoint was in progress", "while rollback to savepoint was in progress",
transactionId); transactionId);
} }
notifyAllWaitingTransactions();
} }
} }
...@@ -412,14 +412,26 @@ public class Transaction { ...@@ -412,14 +412,26 @@ public class Transaction {
* Roll the transaction back. Afterwards, this transaction is closed. * Roll the transaction back. Afterwards, this transaction is closed.
*/ */
public void rollback() { public void rollback() {
Throwable ex = null;
try { try {
long lastState = setStatus(STATUS_ROLLED_BACK); long lastState = setStatus(STATUS_ROLLED_BACK);
long logId = getLogId(lastState); long logId = getLogId(lastState);
if (logId > 0) { if (logId > 0) {
store.rollbackTo(this, logId, 0); store.rollbackTo(this, logId, 0);
} }
} catch (Throwable e) {
ex = e;
throw e;
} finally { } finally {
store.endTransaction(this, true); try {
store.endTransaction(this, true);
} catch (Throwable e) {
if (ex == null) {
throw e;
} else {
ex.addSuppressed(e);
}
}
} }
} }
......
...@@ -168,9 +168,12 @@ abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue> { ...@@ -168,9 +168,12 @@ abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue> {
} }
logIt(existingValue); logIt(existingValue);
return setDecision(MVMap.Decision.PUT); return setDecision(MVMap.Decision.PUT);
} else if (isCommitted(blockingId) && existingValue.value == null) { } else if (isCommitted(blockingId)) {
// entry belongs to a committing transaction // entry belongs to a committing transaction
// and therefore will be committed soon // and therefore will be committed soon
if(existingValue.value != null) {
return setDecision(MVMap.Decision.ABORT);
}
logIt(null); logIt(null);
return setDecision(MVMap.Decision.PUT); return setDecision(MVMap.Decision.PUT);
} else if (getBlockingTransaction() != null) { } else if (getBlockingTransaction() != null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论