提交 79cad4d1 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #468 from andreitokar/Issue#467

Fixes h2database/h2database#467 Deadlock between Sequence.flush() and…
...@@ -1216,7 +1216,8 @@ public class Database implements DataHandler { ...@@ -1216,7 +1216,8 @@ public class Database implements DataHandler {
* @param fromShutdownHook true if this method is called from the shutdown * @param fromShutdownHook true if this method is called from the shutdown
* hook * hook
*/ */
synchronized void close(boolean fromShutdownHook) { void close(boolean fromShutdownHook) {
synchronized (this) {
if (closing) { if (closing) {
return; return;
} }
...@@ -1256,6 +1257,7 @@ public class Database implements DataHandler { ...@@ -1256,6 +1257,7 @@ public class Database implements DataHandler {
} }
closing = true; closing = true;
} }
}
removeOrphanedLobs(); removeOrphanedLobs();
try { try {
if (systemSession != null) { if (systemSession != null) {
......
...@@ -32,7 +32,7 @@ public class Sequence extends SchemaObjectBase { ...@@ -32,7 +32,7 @@ public class Sequence extends SchemaObjectBase {
private long maxValue; private long maxValue;
private boolean cycle; private boolean cycle;
private boolean belongsToTable; private boolean belongsToTable;
private Object flushSync = new Object(); private final Object flushSync = new Object();
private boolean writeWithMargin; private boolean writeWithMargin;
/** /**
...@@ -294,22 +294,19 @@ public class Sequence extends SchemaObjectBase { ...@@ -294,22 +294,19 @@ public class Sequence extends SchemaObjectBase {
// locked it) because it must be committed immediately, otherwise // locked it) because it must be committed immediately, otherwise
// other threads can not access the sys table. // other threads can not access the sys table.
Session sysSession = database.getSystemSession(); Session sysSession = database.getSystemSession();
synchronized (sysSession) { synchronized (database.isMultiThreaded() ? sysSession : database) {
synchronized (flushSync) {
flushInternal(sysSession); flushInternal(sysSession);
}
sysSession.commit(false); sysSession.commit(false);
} }
} else { } else {
synchronized (session) { synchronized (database.isMultiThreaded() ? session : database) {
synchronized (flushSync) {
flushInternal(session); flushInternal(session);
} }
} }
} }
}
private void flushInternal(Session session) { private void flushInternal(Session session) {
synchronized (flushSync) {
final boolean metaWasLocked = database.lockMeta(session); final boolean metaWasLocked = database.lockMeta(session);
// just for this case, use the value with the margin // just for this case, use the value with the margin
try { try {
...@@ -322,6 +319,7 @@ public class Sequence extends SchemaObjectBase { ...@@ -322,6 +319,7 @@ public class Sequence extends SchemaObjectBase {
database.unlockMeta(session); database.unlockMeta(session);
} }
} }
}
/** /**
* Flush the current value to disk and close this object. * Flush the current value to disk and close this object.
......
...@@ -26,11 +26,6 @@ public class TestKillRestart extends TestBase { ...@@ -26,11 +26,6 @@ public class TestKillRestart extends TestBase {
if (config.networked) { if (config.networked) {
return; return;
} }
if (config.fast) {
// using fast as a proxy for "running on Jenkins CI" where this test
// gets stuck waiting for the sub-process after killing it
return;
}
if (getBaseDir().indexOf(':') > 0) { if (getBaseDir().indexOf(':') > 0) {
return; return;
} }
......
...@@ -39,11 +39,6 @@ public class TestKillRestartMulti extends TestBase { ...@@ -39,11 +39,6 @@ public class TestKillRestartMulti extends TestBase {
if (config.networked) { if (config.networked) {
return; return;
} }
if (config.fast) {
// using fast as a proxy for "running on Jenkins CI" where this test
// gets stuck waiting for the sub-process after killing it
return;
}
if (getBaseDir().indexOf(':') > 0) { if (getBaseDir().indexOf(':') > 0) {
return; return;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论