提交 9ec2fad0 authored 作者: Noel Grandin's avatar Noel Grandin

fix deadlock

need to take the TransactionStore RWLock before we synchronize on the
MVMap
上级 67310c61
...@@ -946,6 +946,8 @@ public class TransactionStore { ...@@ -946,6 +946,8 @@ public class TransactionStore {
* @return the size * @return the size
*/ */
public long sizeAsLong() { public long sizeAsLong() {
transaction.store.rwLock.readLock().lock();
try {
long sizeRaw = map.sizeAsLong(); long sizeRaw = map.sizeAsLong();
MVMap<Long, Object[]> undo = transaction.store.undoLog; MVMap<Long, Object[]> undo = transaction.store.undoLog;
long undoLogSize; long undoLogSize;
...@@ -962,13 +964,8 @@ public class TransactionStore { ...@@ -962,13 +964,8 @@ public class TransactionStore {
Cursor<K, VersionedValue> cursor = map.cursor(null); Cursor<K, VersionedValue> cursor = map.cursor(null);
while (cursor.hasNext()) { while (cursor.hasNext()) {
VersionedValue data; VersionedValue data;
transaction.store.rwLock.readLock().lock();
try {
K key = cursor.next(); K key = cursor.next();
data = getValue(key, readLogId, cursor.getValue()); data = getValue(key, readLogId, cursor.getValue());
} finally {
transaction.store.rwLock.readLock().unlock();
}
if (data != null && data.value != null) { if (data != null && data.value != null) {
size++; size++;
} }
...@@ -980,7 +977,8 @@ public class TransactionStore { ...@@ -980,7 +977,8 @@ public class TransactionStore {
synchronized (undo) { synchronized (undo) {
// re-fetch in case any transaction was committed now // re-fetch in case any transaction was committed now
long size = map.sizeAsLong(); long size = map.sizeAsLong();
MVMap<Object, Integer> temp = transaction.store.createTempMap(); MVMap<Object, Integer> temp = transaction.store
.createTempMap();
try { try {
for (Entry<Long, Object[]> e : undo.entrySet()) { for (Entry<Long, Object[]> e : undo.entrySet()) {
Object[] op = e.getValue(); Object[] op = e.getValue();
...@@ -993,7 +991,8 @@ public class TransactionStore { ...@@ -993,7 +991,8 @@ public class TransactionStore {
K key = (K) op[1]; K key = (K) op[1];
if (get(key) == null) { if (get(key) == null) {
Integer old = temp.put(key, 1); Integer old = temp.put(key, 1);
// count each key only once (there might be multiple // count each key only once (there might be
// multiple
// changes for the same key) // changes for the same key)
if (old == null) { if (old == null) {
size--; size--;
...@@ -1005,6 +1004,9 @@ public class TransactionStore { ...@@ -1005,6 +1004,9 @@ public class TransactionStore {
} }
return size; return size;
} }
} finally {
transaction.store.rwLock.readLock().unlock();
}
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论