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).

Reply via email to