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

eliminate COMMITTED transaction status

上级 80afdcfe
......@@ -32,41 +32,36 @@ public class Transaction {
*/
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
* 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.
* Nevertheless, those changes should be already viewed by other
* 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.
* 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
* 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,
* 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[] = {
"CLOSED", "OPEN", "PREPARED", "COMMITTING",
"COMMITTED", "ROLLING_BACK", "ROLLED_BACK"
"CLOSED", "OPEN", "PREPARED", "COMMITTED", "ROLLING_BACK", "ROLLED_BACK"
};
static final int LOG_ID_BITS = 40;
private static final int LOG_ID_BITS1 = LOG_ID_BITS + 1;
......@@ -175,6 +170,11 @@ public class Transaction {
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) {
while (true) {
long currentState = statusAndLogId.get();
......@@ -199,16 +199,12 @@ public class Transaction {
// from endLeftoverTransactions()
currentStatus == STATUS_COMMITTING;
break;
case STATUS_COMMITTED:
valid = currentStatus == STATUS_COMMITTING;
break;
case STATUS_ROLLED_BACK:
valid = currentStatus == STATUS_OPEN ||
currentStatus == STATUS_PREPARED;
break;
case STATUS_CLOSED:
valid = currentStatus == STATUS_COMMITTING ||
currentStatus == STATUS_COMMITTED ||
currentStatus == STATUS_ROLLED_BACK;
break;
default:
......@@ -367,8 +363,9 @@ public class Transaction {
try {
long state = setStatus(STATUS_COMMITTING);
hasChanges = hasChanges(state);
int previousStatus = getStatus(state);
if (hasChanges) {
store.commit(this);
store.commit(this, previousStatus == STATUS_COMMITTING);
}
} catch (Throwable e) {
ex = e;
......
......@@ -146,10 +146,6 @@ public class TransactionStore {
* in which case the store can only be used for reading.
*/
public void init() {
init(RollbackListener.NONE);
}
public synchronized void init(RollbackListener listener) {
if (!init) {
// remove all temporary maps
for (String mapName : store.getMapNames()) {
......@@ -182,7 +178,7 @@ public class TransactionStore {
assert lastUndoKey != null;
assert getTransactionId(lastUndoKey) == transactionId;
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 {
transactions.set(transactionId, transaction);
if (undoLogs[transactionId] == null) {
String undoName = getUndoLogName(false, transactionId);
undoLogs[transactionId] = store.openMap(undoName, undoLogBuilder);
String undoName = getUndoLogName(status == Transaction.STATUS_COMMITTING, transactionId);
MVMap<Long, Object[]> undoLog = store.openMap(undoName, undoLogBuilder);
undoLogs[transactionId] = undoLog;
}
return transaction;
}
......@@ -412,8 +409,10 @@ public class TransactionStore {
/**
* Commit a transaction.
* @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()) {
int transactionId = t.transactionId;
// this is an atomic action that causes all changes
......@@ -422,9 +421,10 @@ public class TransactionStore {
CommitDecisionMaker commitDecisionMaker = new CommitDecisionMaker();
try {
t.setStatus(Transaction.STATUS_COMMITTED);
MVMap<Long, Object[]> undoLog = undoLogs[transactionId];
store.renameMap(undoLog, getUndoLogName(true, transactionId));
if(!recovery) {
store.renameMap(undoLog, getUndoLogName(true, transactionId));
}
try {
Cursor<Long, Object[]> cursor = undoLog.cursor(null);
while (cursor.hasNext()) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论