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

eliminate COMMITTED transaction status

上级 80afdcfe
...@@ -32,41 +32,36 @@ public class Transaction { ...@@ -32,41 +32,36 @@ public class Transaction {
*/ */
public static final int STATUS_PREPARED = 2; public static final int STATUS_PREPARED = 2;
/**
* The status of a transaction that is being committed, but possibly not
* yet finished. A transactions can go into this state when the store is
* closed while the transaction is committing. When opening a store,
* such transactions should be committed.
*/
public static final int STATUS_COMMITTING = 3;
/** /**
* The status of a transaction that has been logically committed or rather * The status of a transaction that has been logically committed or rather
* marked as committed, because it might be still listed among prepared, * marked as committed, because it might be still listed among prepared,
* if it was prepared for commit, undo log entries might still exists for it * if it was prepared for commit. Undo log entries might still exists for it
* and not all of it's changes within map's are re-written as committed yet. * and not all of it's changes within map's are re-written as committed yet.
* Nevertheless, those changes should be already viewed by other * Nevertheless, those changes should be already viewed by other
* transactions as committed. * transactions as committed.
* This transaction's id can not be re-used until all the above is completed * This transaction's id can not be re-used until all of the above is completed
* and transaction is closed. * and transaction is closed.
* A transactions can be observed in this state when the store was
* closed while the transaction was not closed yet.
* When opening a store, such transactions will automatically
* be processed and closed as committed.
*/ */
public static final int STATUS_COMMITTED = 4; public static final int STATUS_COMMITTING = 3;
/** /**
* The status of a transaction that currently in a process of rolling back * The status of a transaction that currently in a process of rolling back
* to a savepoint. * to a savepoint.
*/ */
private static final int STATUS_ROLLING_BACK = 5; private static final int STATUS_ROLLING_BACK = 4;
/** /**
* The status of a transaction that has been rolled back completely, * The status of a transaction that has been rolled back completely,
* but undo operations are not finished yet. * but undo operations are not finished yet.
*/ */
private static final int STATUS_ROLLED_BACK = 6; private static final int STATUS_ROLLED_BACK = 5;
private static final String STATUS_NAMES[] = { private static final String STATUS_NAMES[] = {
"CLOSED", "OPEN", "PREPARED", "COMMITTING", "CLOSED", "OPEN", "PREPARED", "COMMITTED", "ROLLING_BACK", "ROLLED_BACK"
"COMMITTED", "ROLLING_BACK", "ROLLED_BACK"
}; };
static final int LOG_ID_BITS = 40; static final int LOG_ID_BITS = 40;
private static final int LOG_ID_BITS1 = LOG_ID_BITS + 1; private static final int LOG_ID_BITS1 = LOG_ID_BITS + 1;
...@@ -175,6 +170,11 @@ public class Transaction { ...@@ -175,6 +170,11 @@ public class Transaction {
return getStatus(statusAndLogId.get()); return getStatus(statusAndLogId.get());
} }
/**
* Changes transaction status to a specified value
* @param status to be set
* @return transaction state as it was before status change
*/
long setStatus(int status) { long setStatus(int status) {
while (true) { while (true) {
long currentState = statusAndLogId.get(); long currentState = statusAndLogId.get();
...@@ -199,16 +199,12 @@ public class Transaction { ...@@ -199,16 +199,12 @@ public class Transaction {
// from endLeftoverTransactions() // from endLeftoverTransactions()
currentStatus == STATUS_COMMITTING; currentStatus == STATUS_COMMITTING;
break; break;
case STATUS_COMMITTED:
valid = currentStatus == STATUS_COMMITTING;
break;
case STATUS_ROLLED_BACK: case STATUS_ROLLED_BACK:
valid = currentStatus == STATUS_OPEN || valid = currentStatus == STATUS_OPEN ||
currentStatus == STATUS_PREPARED; currentStatus == STATUS_PREPARED;
break; break;
case STATUS_CLOSED: case STATUS_CLOSED:
valid = currentStatus == STATUS_COMMITTING || valid = currentStatus == STATUS_COMMITTING ||
currentStatus == STATUS_COMMITTED ||
currentStatus == STATUS_ROLLED_BACK; currentStatus == STATUS_ROLLED_BACK;
break; break;
default: default:
...@@ -367,8 +363,9 @@ public class Transaction { ...@@ -367,8 +363,9 @@ public class Transaction {
try { try {
long state = setStatus(STATUS_COMMITTING); long state = setStatus(STATUS_COMMITTING);
hasChanges = hasChanges(state); hasChanges = hasChanges(state);
int previousStatus = getStatus(state);
if (hasChanges) { if (hasChanges) {
store.commit(this); store.commit(this, previousStatus == STATUS_COMMITTING);
} }
} catch (Throwable e) { } catch (Throwable e) {
ex = e; ex = e;
......
...@@ -146,10 +146,6 @@ public class TransactionStore { ...@@ -146,10 +146,6 @@ public class TransactionStore {
* in which case the store can only be used for reading. * in which case the store can only be used for reading.
*/ */
public void init() { public void init() {
init(RollbackListener.NONE);
}
public synchronized void init(RollbackListener listener) {
if (!init) { if (!init) {
// remove all temporary maps // remove all temporary maps
for (String mapName : store.getMapNames()) { for (String mapName : store.getMapNames()) {
...@@ -182,7 +178,7 @@ public class TransactionStore { ...@@ -182,7 +178,7 @@ public class TransactionStore {
assert lastUndoKey != null; assert lastUndoKey != null;
assert getTransactionId(lastUndoKey) == transactionId; assert getTransactionId(lastUndoKey) == transactionId;
long logId = getLogId(lastUndoKey) + 1; long logId = getLogId(lastUndoKey) + 1;
registerTransaction(transactionId, status, name, logId, timeoutMillis, 0, listener); registerTransaction(transactionId, status, name, logId, timeoutMillis, 0, RollbackListener.NONE);
} }
} }
} }
...@@ -341,8 +337,9 @@ public class TransactionStore { ...@@ -341,8 +337,9 @@ public class TransactionStore {
transactions.set(transactionId, transaction); transactions.set(transactionId, transaction);
if (undoLogs[transactionId] == null) { if (undoLogs[transactionId] == null) {
String undoName = getUndoLogName(false, transactionId); String undoName = getUndoLogName(status == Transaction.STATUS_COMMITTING, transactionId);
undoLogs[transactionId] = store.openMap(undoName, undoLogBuilder); MVMap<Long, Object[]> undoLog = store.openMap(undoName, undoLogBuilder);
undoLogs[transactionId] = undoLog;
} }
return transaction; return transaction;
} }
...@@ -412,8 +409,10 @@ public class TransactionStore { ...@@ -412,8 +409,10 @@ public class TransactionStore {
/** /**
* Commit a transaction. * Commit a transaction.
* @param t transaction to commit * @param t transaction to commit
* @param recovery if called during initial transaction recovery procedure
* therefore undo log is stored under "committed" name already
*/ */
void commit(Transaction t) { void commit(Transaction t, boolean recovery) {
if (!store.isClosed()) { if (!store.isClosed()) {
int transactionId = t.transactionId; int transactionId = t.transactionId;
// this is an atomic action that causes all changes // this is an atomic action that causes all changes
...@@ -422,9 +421,10 @@ public class TransactionStore { ...@@ -422,9 +421,10 @@ public class TransactionStore {
CommitDecisionMaker commitDecisionMaker = new CommitDecisionMaker(); CommitDecisionMaker commitDecisionMaker = new CommitDecisionMaker();
try { try {
t.setStatus(Transaction.STATUS_COMMITTED);
MVMap<Long, Object[]> undoLog = undoLogs[transactionId]; MVMap<Long, Object[]> undoLog = undoLogs[transactionId];
store.renameMap(undoLog, getUndoLogName(true, transactionId)); if(!recovery) {
store.renameMap(undoLog, getUndoLogName(true, transactionId));
}
try { try {
Cursor<Long, Object[]> cursor = undoLog.cursor(null); Cursor<Long, Object[]> cursor = undoLog.cursor(null);
while (cursor.hasNext()) { while (cursor.hasNext()) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论