diff options
author | Eike Stepper | 2018-05-02 11:27:46 +0000 |
---|---|---|
committer | Eike Stepper | 2018-05-02 11:27:46 +0000 |
commit | 52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62 (patch) | |
tree | e244ba54a213cd4118b453a16aa2b156cb62c824 /plugins/org.eclipse.net4j.db | |
parent | b1cf5c385c916946ea044f0325b74b3907c262ed (diff) | |
download | cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.tar.gz cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.tar.xz cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.zip |
[534254] [DB] Create all mapped tables lazily
https://bugs.eclipse.org/bugs/show_bug.cgi?id=534254
Diffstat (limited to 'plugins/org.eclipse.net4j.db')
6 files changed, 116 insertions, 43 deletions
diff --git a/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF index 63f0e1c58f..a56d80f2d5 100644 --- a/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.net4j.db;singleton:=true -Bundle-Version: 4.6.100.qualifier +Bundle-Version: 4.7.0.qualifier Bundle-Activator: org.eclipse.net4j.internal.db.bundle.OM$Activator Bundle-Vendor: %providerName Bundle-ClassPath: . @@ -11,17 +11,17 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.db.jdbc;bundle-version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.net4j.db;version="4.6.100", - org.eclipse.net4j.db.ddl;version="4.6.100", - org.eclipse.net4j.db.ddl.delta;version="4.6.100", - org.eclipse.net4j.db.dml;version="4.6.100", - org.eclipse.net4j.internal.db;version="4.6.100";x-internal:=true, - org.eclipse.net4j.internal.db.bundle;version="4.6.100";x-internal:=true, - org.eclipse.net4j.internal.db.ddl;version="4.6.100";x-friends:="org.eclipse.emf.cdo.server.db", - org.eclipse.net4j.internal.db.ddl.delta;version="4.6.100";x-internal:=true, - org.eclipse.net4j.internal.db.dml;version="4.6.100";x-internal:=true, - org.eclipse.net4j.spi.db;version="4.6.100", - org.eclipse.net4j.spi.db.ddl;version="4.6.100" +Export-Package: org.eclipse.net4j.db;version="4.7.0", + org.eclipse.net4j.db.ddl;version="4.7.0", + org.eclipse.net4j.db.ddl.delta;version="4.7.0", + org.eclipse.net4j.db.dml;version="4.7.0", + org.eclipse.net4j.internal.db;version="4.7.0";x-internal:=true, + org.eclipse.net4j.internal.db.bundle;version="4.7.0";x-internal:=true, + org.eclipse.net4j.internal.db.ddl;version="4.7.0";x-friends:="org.eclipse.emf.cdo.server.db", + org.eclipse.net4j.internal.db.ddl.delta;version="4.7.0";x-internal:=true, + org.eclipse.net4j.internal.db.dml;version="4.7.0";x-internal:=true, + org.eclipse.net4j.spi.db;version="4.7.0", + org.eclipse.net4j.spi.db.ddl;version="4.7.0" Bundle-ActivationPolicy: lazy Eclipse-BuddyPolicy: registered Automatic-Module-Name: org.eclipse.net4j.db diff --git a/plugins/org.eclipse.net4j.db/pom.xml b/plugins/org.eclipse.net4j.db/pom.xml index fa80a1808a..df0ef3a7e1 100644 --- a/plugins/org.eclipse.net4j.db/pom.xml +++ b/plugins/org.eclipse.net4j.db/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.net4j.db</artifactId> - <version>4.6.100-SNAPSHOT</version> + <version>4.7.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java index 2eb04118e4..24b9a477c9 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java @@ -32,6 +32,15 @@ public interface IDBDatabase extends IContainer<IDBConnection>, IDBConnectionPro public IDBSchemaTransaction openSchemaTransaction(); + /** + * @since 4.7 + */ + public IDBSchemaTransaction openSchemaTransaction(IDBConnection connection); + + /** + * @deprecated As of 4.7 no longer supported in favor of support for multiple schema transactions. + */ + @Deprecated public IDBSchemaTransaction getSchemaTransaction(); public void updateSchema(RunnableWithSchema runnable); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java index 45998e809c..13e66b454d 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java @@ -84,8 +84,7 @@ public final class DBConnection extends DelegatingConnection implements IDBConne public IDBSchemaTransaction openSchemaTransaction() { - DBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); - schemaTransaction.setConnection(this); + DBSchemaTransaction schemaTransaction = database.openSchemaTransaction(this); return schemaTransaction; } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java index 5df41b046f..9247b31957 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java @@ -22,8 +22,11 @@ import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta; import org.eclipse.net4j.spi.db.DBAdapter; import org.eclipse.net4j.spi.db.ddl.InternalDBSchema; import org.eclipse.net4j.util.WrappedException; +import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException; import org.eclipse.net4j.util.container.SetContainer; import org.eclipse.net4j.util.event.Event; +import org.eclipse.net4j.util.io.IOUtil; +import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.util.security.IUserAware; import java.sql.Connection; @@ -35,6 +38,11 @@ import java.util.LinkedList; */ public final class DBDatabase extends SetContainer<IDBConnection> implements IDBDatabase { + private static final long TIMEOUT_SCHEMA_ACCESS = Long + .parseLong(OMPlatform.INSTANCE.getProperty("org.eclipse.net4j.internal.db.DBDatabase.TIMEOUT_SCHEMA_ACCESS", "15000")); + + private static final boolean DEBUG_SCHEMA_ACCESS = OMPlatform.INSTANCE.isProperty("org.eclipse.net4j.internal.db.DBDatabase.DEBUG_SCHEMA_ACCESS"); + private DBAdapter adapter; private IDBConnectionProvider connectionProvider; @@ -43,10 +51,10 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB private IDBSchema schema; - private DBSchemaTransaction schemaTransaction; - private final LinkedList<SchemaAccess> schemaAccessQueue = new LinkedList<SchemaAccess>(); + private int schemaWriters; + public DBDatabase(final DBAdapter adapter, IDBConnectionProvider connectionProvider, final String schemaName, final boolean fixNullableIndexColumns) { super(IDBConnection.class); @@ -87,13 +95,23 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB public DBSchemaTransaction openSchemaTransaction() { + return openSchemaTransaction(null); + } + + public DBSchemaTransaction openSchemaTransaction(IDBConnection connection) + { DBSchemaTransaction schemaTransaction = new DBSchemaTransaction(this); - this.schemaTransaction = schemaTransaction; + schemaTransaction.setConnection((DBConnection)connection); return schemaTransaction; } public void closeSchemaTransaction(DBSchemaDelta delta) { + if (delta == null || delta.isEmpty()) + { + return; + } + try { beginSchemaAccess(true); @@ -103,18 +121,18 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB ((DBConnection)transaction).invalidateStatementCache(); } - fireEvent(new SchemaChangedEventImpl(delta)); + fireEvent(new SchemaChangedEventImpl(this, delta)); } finally { - schemaTransaction = null; endSchemaAccess(); } } + @Deprecated public DBSchemaTransaction getSchemaTransaction() { - return schemaTransaction; + throw new UnsupportedOperationException(); } public void updateSchema(RunnableWithSchema runnable) @@ -191,6 +209,18 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB public void beginSchemaAccess(boolean write) { + if (DEBUG_SCHEMA_ACCESS) + { + try + { + throw new Exception("Begin " + (write ? "write" : "read") + " schema access: " + schema.getName()); + } + catch (Exception ex) + { + ex.printStackTrace(IOUtil.OUT()); + } + } + SchemaAccess schemaAccess = null; synchronized (schemaAccessQueue) { @@ -198,10 +228,11 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB { schemaAccess = new WriteSchemaAccess(); schemaAccessQueue.addLast(schemaAccess); + ++schemaWriters; } else { - if (!schemaAccessQueue.isEmpty()) + if (schemaWriters == 0 && !schemaAccessQueue.isEmpty()) { schemaAccess = schemaAccessQueue.getFirst(); if (schemaAccess instanceof ReadSchemaAccess) @@ -223,29 +254,52 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB } } - for (;;) + long end = System.currentTimeMillis() + TIMEOUT_SCHEMA_ACCESS; + + do { synchronized (schemaAccessQueue) { if (schemaAccessQueue.getFirst() == schemaAccess) { + if (write) + { + --schemaWriters; + } + return; } try { - schemaAccessQueue.wait(); + schemaAccessQueue.wait(1000L); } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); throw WrappedException.wrap(ex); } } - } + } while (System.currentTimeMillis() < end); + + throw new TimeoutRuntimeException( + "Schema " + schema.getName() + " could not be locked for " + (write ? "write" : "read") + " access within " + TIMEOUT_SCHEMA_ACCESS + " milliseconds"); } public void endSchemaAccess() { + if (DEBUG_SCHEMA_ACCESS) + { + try + { + throw new Exception("End schema access: " + schema.getName()); + } + catch (Exception ex) + { + ex.printStackTrace(IOUtil.OUT()); + } + } + synchronized (schemaAccessQueue) { SchemaAccess schemaAccess = schemaAccessQueue.getFirst(); @@ -288,7 +342,7 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB /** * @author Eike Stepper */ - private final class ReadSchemaAccess implements SchemaAccess + private static final class ReadSchemaAccess implements SchemaAccess { private int readers = 1; @@ -312,7 +366,7 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB /** * @author Eike Stepper */ - private final class WriteSchemaAccess implements SchemaAccess + private static final class WriteSchemaAccess implements SchemaAccess { @Override public String toString() @@ -324,15 +378,15 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB /** * @author Eike Stepper */ - private final class SchemaChangedEventImpl extends Event implements SchemaChangedEvent + private static final class SchemaChangedEventImpl extends Event implements SchemaChangedEvent { private static final long serialVersionUID = 1L; private final IDBSchemaDelta schemaDelta; - public SchemaChangedEventImpl(IDBSchemaDelta schemaDelta) + public SchemaChangedEventImpl(DBDatabase database, IDBSchemaDelta schemaDelta) { - super(DBDatabase.this); + super(database); this.schemaDelta = schemaDelta; } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java index 970a166624..525766124e 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java @@ -37,6 +37,8 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable private IDBSchema oldSchema; + private IDBSchema oldSchemaCopy; + private IDBSchema workingCopy; public DBSchemaTransaction(DBDatabase database) @@ -44,6 +46,8 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable this.database = database; oldSchema = database.getSchema(); + oldSchemaCopy = DBUtil.copySchema(oldSchema); + IDBSchema copy = DBUtil.copySchema(oldSchema); workingCopy = DelegatingDBSchemaElement.wrap(copy); } @@ -89,7 +93,7 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable public DBSchemaDelta getSchemaDelta() { - return (DBSchemaDelta)workingCopy.compare(oldSchema); + return (DBSchemaDelta)workingCopy.compare(oldSchemaCopy); } public DBSchemaDelta commit() @@ -99,6 +103,9 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable return DBUtil.execute(database, this); } + // Remember connection locally because the instance field will be reset in run/doClose. + DBConnection connection = this.connection; + try { DBSchemaDelta result = run(connection); @@ -116,19 +123,22 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable { DBSchemaDelta delta = getSchemaDelta(); - try - { - ((InternalDBSchema)oldSchema).unlock(); - - DBAdapter adapter = database.getAdapter(); - adapter.updateSchema(connection, oldSchema, delta); - - ((DelegatingDBSchema)workingCopy).setDelegate(oldSchema); - } - finally + synchronized (oldSchema) { - ((InternalDBSchema)oldSchema).lock(); - doClose(delta); + try + { + ((InternalDBSchema)oldSchema).unlock(); + + DBAdapter adapter = database.getAdapter(); + adapter.updateSchema(connection, oldSchema, delta); + + ((DelegatingDBSchema)workingCopy).setDelegate(oldSchema); + } + finally + { + ((InternalDBSchema)oldSchema).lock(); + doClose(delta); + } } return delta; @@ -146,6 +156,7 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable database.closeSchemaTransaction(delta); connection = null; oldSchema = null; + oldSchemaCopy = null; workingCopy = null; } } |