提交 2184b359 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVTableEngine: concurrency

上级 1d417475
......@@ -103,7 +103,7 @@ public class TransactionStore {
init();
}
private void init() {
private synchronized void init() {
String s = settings.get(LAST_TRANSACTION_ID);
if (s != null) {
lastTransactionId = Long.parseLong(s);
......@@ -115,18 +115,21 @@ public class TransactionStore {
DataUtils.ERROR_TRANSACTION_CORRUPT,
"Last transaction not stored");
}
synchronized (undoLog) {
if (undoLog.size() > 0) {
long[] key = undoLog.firstKey();
firstOpenTransaction = key[0];
}
}
}
/**
* Get the list of unclosed transactions that have pending writes.
*
* @return the list of transactions (sorted by id)
*/
public synchronized List<Transaction> getOpenTransactions() {
public List<Transaction> getOpenTransactions() {
synchronized (undoLog) {
ArrayList<Transaction> list = New.arrayList();
long[] key = undoLog.firstKey();
while (key != null) {
......@@ -150,6 +153,7 @@ public class TransactionStore {
}
return list;
}
}
/**
* Close the transaction store.
......@@ -187,7 +191,7 @@ public class TransactionStore {
*
* @param t the transaction
*/
void storeTransaction(Transaction t) {
synchronized void storeTransaction(Transaction t) {
if (t.getStatus() == Transaction.STATUS_PREPARED || t.getName() != null) {
Object[] v = { t.getStatus(), t.getName() };
preparedTransactions.put(t.getId(), v);
......@@ -209,7 +213,9 @@ public class TransactionStore {
commitIfNeeded();
long[] undoKey = { t.getId(), logId };
Object[] log = new Object[] { opType, mapId, key, oldValue };
synchronized (undoLog) {
undoLog.put(undoKey, log);
}
if (firstOpenTransaction == -1 || t.getId() < firstOpenTransaction) {
firstOpenTransaction = t.getId();
}
......@@ -225,6 +231,7 @@ public class TransactionStore {
if (store.isClosed()) {
return;
}
synchronized (undoLog) {
for (long logId = 0; logId < maxLogId; logId++) {
commitIfNeeded();
long[] undoKey = new long[] { t.getId(), logId };
......@@ -246,10 +253,11 @@ public class TransactionStore {
}
undoLog.remove(undoKey);
}
}
endTransaction(t);
}
private MVMap<Object, VersionedValue> openMap(int mapId) {
private synchronized MVMap<Object, VersionedValue> openMap(int mapId) {
// TODO open map by id if possible
Map<String, String> meta = store.getMetaMap();
String m = meta.get("map." + mapId);
......@@ -277,6 +285,7 @@ public class TransactionStore {
if (transactionId < firstOpenTransaction) {
return false;
}
synchronized (undoLog) {
if (firstOpenTransaction == -1) {
if (undoLog.size() == 0) {
return false;
......@@ -295,13 +304,14 @@ public class TransactionStore {
key = undoLog.higherKey(key);
return key != null && key[0] == transactionId;
}
}
/**
* End this transaction
*
* @param t the transaction
*/
void endTransaction(Transaction t) {
synchronized void endTransaction(Transaction t) {
if (t.getStatus() == Transaction.STATUS_PREPARED) {
preparedTransactions.remove(t.getId());
}
......@@ -322,6 +332,7 @@ public class TransactionStore {
* @param toLogId the log id to roll back to
*/
void rollbackTo(Transaction t, long maxLogId, long toLogId) {
synchronized (undoLog) {
for (long logId = maxLogId - 1; logId >= toLogId; logId--) {
commitIfNeeded();
long[] undoKey = new long[] { t.getId(), logId };
......@@ -342,6 +353,7 @@ public class TransactionStore {
undoLog.remove(undoKey);
}
}
}
/**
* Get the changes of the given transaction, starting from the latest log id
......@@ -363,6 +375,7 @@ public class TransactionStore {
}
private void fetchNext() {
synchronized (undoLog) {
while (logId >= toLogId) {
Object[] op = undoLog.get(new long[] {
t.getId(), logId });
......@@ -382,6 +395,7 @@ public class TransactionStore {
return;
}
}
}
current = null;
}
......@@ -958,10 +972,12 @@ public class TransactionStore {
}
// get the value before the uncommitted transaction
long[] x = new long[] { tx, logId };
synchronized (transaction.store.undoLog) {
Object[] d = transaction.store.undoLog.get(x);
data = (VersionedValue) d[3];
}
}
}
/**
......
......@@ -680,10 +680,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new TestRandomCompare().runTest(this);
new TestKillRestart().runTest(this);
new TestKillRestartMulti().runTest(this);
if (!mvStore) {
// concurrent modification of the undoLog
new TestMultiThreaded().runTest(this);
}
new TestOuterJoins().runTest(this);
new TestNestedJoins().runTest(this);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论