Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2018-05-02 11:27:46 +0000
committerEike Stepper2018-05-02 11:27:46 +0000
commit52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62 (patch)
treee244ba54a213cd4118b453a16aa2b156cb62c824 /plugins/org.eclipse.net4j.db
parentb1cf5c385c916946ea044f0325b74b3907c262ed (diff)
downloadcdo-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')
-rw-r--r--plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF24
-rw-r--r--plugins/org.eclipse.net4j.db/pom.xml2
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java9
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java3
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java84
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java37
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;
}
}

Back to the top