Dear Damian,
thanks for your response.
> Without seeing getDataSource() it's not complete, but I don't see any obvious
> issues.
getDataSource() just returns a static instance of a BasicDataSource
(commons-dbcp 1.4) configured as follows
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"
/>
<property name="url"
value="jdbc:mysql://localhost/tie?autoReconnect=true" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="removeAbandoned" value="true"/>
<property name="maxIdle" value="5"/>
</bean>
> As you indicate, using only one connection may not be ideal.
Clear. But still, it should be just a performance issue, not a semantics issue.
Right ?
> private static final StoreDesc storeDesc = new
> StoreDesc(LayoutType.LayoutTripleNodesHash,
> DatabaseType.MySQL);
> private final static Store store;
>
> static {
> JDBC.loadDriverMySQL();
> try {
> store = SDBFactory.connectStore(new
> SDBConnection(getDataSource()),storeDesc);
> if (!StoreUtils.isFormatted(store)) {
> store.getTableFormatter().create();
> }
> } catch (SQLException ex) {
> System.err.println("Exception occured when formatting a new
> store: " + ex.getMessage());
> throw new RuntimeException(ex);
> }
> }
>
> private Model getOntModel(String modelName) {
> synchronized (store) {
> return SDBFactory.connectNamedModel(store, modelName);
> }
> }
>
> The problem is that in a very non-deterministic manner
Uh-oh.
> we get
>
> com.hp.hpl.jena.sdb.SDBException: Exception flushing
>
> com.hp.hpl.jena.sdb.layout2.TupleLoaderBase.flush(TupleLoaderBase.java:220)
>
> com.hp.hpl.jena.sdb.layout2.TupleLoaderBase.finish(TupleLoaderBase.java:155)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes.commitTuples(LoaderTuplesNodes.java:283)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes.access$100(LoaderTuplesNodes.java:31)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes$Commiter.run(LoaderTuplesNodes.java:318)
> java.lang.Thread.run(Thread.java:662)
> root cause
>
> java.sql.BatchUpdateException: Table 'tie.NNodeQuads' doesn't exist
>
> com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020)
>
> com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
>
> org.apache.commons.dbcp.DelegatingPreparedStatement.executeBatch(DelegatingPreparedStatement.java:205)
>
> com.hp.hpl.jena.sdb.layout2.TupleLoaderBase.flush(TupleLoaderBase.java:200)
>
> com.hp.hpl.jena.sdb.layout2.TupleLoaderBase.finish(TupleLoaderBase.java:155)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes.commitTuples(LoaderTuplesNodes.java:283)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes.access$100(LoaderTuplesNodes.java:31)
>
> com.hp.hpl.jena.sdb.layout2.LoaderTuplesNodes$Commiter.run(LoaderTuplesNodes.java:318)
> java.lang.Thread.run(Thread.java:662)
>
> What I understand from the source of TupleLoaderBase, the NNodeQuads table is
> only a
temporary one. Thus it might be a race problem on the underlying mysql
connection within SDB
?
> What does your loading code look like?
There is lots of loading code distributed along the application, so it is not
so easy to find out which exact part failed. Anyway, any R/W operation is
performed on an OntModel obtained from
private Model getOntModel(String modelName);
> Obvious question: you aren't closing the store anywhere, are you?
Of course not - this is exactly the problem - I can't. The design of the
application is rather poor and was probably made with the intention that the
model obtained by getOntModel is memory-based. Thus, I just create the model
and provide it to whichever part of the application requests it. So, as soon as
I create the OntModel, I do not have the control over its life anymore. This is
exactly the reason, why creating a connection-pool based solution would take
some time, as another API, finer-grained comparing to "private Model
getOntModel(String modelName);", would have to be designed and vast parts of
the application would have to be reimplemented to that API.
> Next obvious question: could more than one thread be accessing the store at
> the same time?
The application is web based and no user-defined threads are created. To
prevent concurrent access from different web threads I have synchronized the
access to the store (see above) object. Maybe the synchronization should be
done on another place ...
>I see nothing wrong with what you're doing here, but it isn't a complete
>example. Issues with mysql jdbc drivers isn't unheard off.
One thing - If I create multiple models from the same Store object - are they
synchronized over the connection object provided to the Store object at its
creation time ?
Thanks for Your help
Petr
--
The Open University is incorporated by Royal Charter (RC 000391), an exempt
charity in England & Wales and a charity registered in Scotland (SC 038302).