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

MVTableEngine: concurrency

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