You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Andreas Grünwald <a....@gmail.com> on 2013/09/29 00:46:10 UTC

Jena TDB and Transactions ?

Hello,
I am trying to implement proper transaction handling based on the latest
Jena TDB version.

This is how I roughly initialize the model entities (I work with Jena's
OntModel):

class ConnectorWrapper
   public void init() {
      Dataset tdbDataSet = TDBFactory.createDataset(directory);
      model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
       this.ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
model);
   }
}

I ran into some problems.

   1. tdbDataSet.abort() is not working for me. As far as I got from the
   documentation, the OwlModel does not support transactions. Did I got that
   correct? Is there any kind of workaround?

   2. How do I properly close/destroy a Jena Dataset? I am running into the
   situation that I have several "Connector" instances (within one Thread),
   which wrap an instance of the Jena Dataset. However, only the first
   initialization succeeds, for the latter I get something like "transaction
   is not active". I also get some errors in the command line "ERROR
   com.hp.hpl.jena.tdb.transaction.BlockMgrJournal - **** Not active: 1"
   although I call "tdbDataSet.close() and tdbDataSet.end()" before calling
   init() again. Is TDBFactory.createDataset(directory) the correct way to
   retrieve a dataset-instance, or should I call another method? Does my
   initialization approach seem ok?

Thank you very much and best regards,
Andreas

Re: Jena TDB and Transactions ?

Posted by Andy Seaborne <an...@apache.org>.
On 30/09/13 22:27, Andreas Grünwald wrote:
> Thanks for your response.
> Actually I am applying the transaction on the tdbDataSet, from which I
> derived the ontmodel. I am performing some changes on the ontModel, and
> then try to abort the transaction with tdbDataSet.abort(). However, the
> changes applied to the ontmodel are already persisted and cannot be undone
> as it seems.

I think the problem is that you have the OntModel across transaction 
boundaries.  You'll need to recreate views (models and ontmodel are 
views) of the database inside a transaction.

	Andy

>
> Here is the unit test which fails:

Not runnable!

>
> @Test
> public void testInsertIndividualButRollback() throws MDDException {
>     String reqId = "req777";
>     JenaTDBConnection c = new JenaTDBConnection(connection data...);
>     c.connect();
>     c.begin();
>
>     OntModel ont = c.getOntologyModel();
>     String ns = c.getOntologySchemaIRI() + "#";
>     OntClass requirement = ont.getOntClass(ns + "Requirement");
>     OntProperty p = ont.getOntProperty(ns + "hasRequirementName");
>     DatatypeProperty pd = ont.getDatatypeProperty(ns + "hasRequirementName");
> //don't know yet which one is correct
>     Individual req1 = ont.createIndividual(ns + name, requirement);
>     req1.addProperty(pd, "individual requirement named 1");
>
>     c.rollback();
>     c.close();
>
>     c.connect();
>     c.begin();
>     Individual reqBack =
> c.getOntologyModel().getIndividual(c.getOntologySchemaIRI()
> + "#" + reqId);
>     c.rollback();
>     c.close();
>
>     *assertTrue(reqBack == null);*



> }
>
> and the related Jena connection wrapper:
>
>
> public class JenaTDBConnection {
>
>     ...
>
>     ...
>
>     @Override
>     public void connect() throws MDDException {
>        modelSpec = createModelSpec();
>        modelSpec.getDocumentManager().setProcessImports(false); //avoid
> reading urls, such as http://www.itpm...
>        String directory = this.host + "/" + this.schema;
>
>        try {
>           if(firstInit) {
>              tdbDataSet = TDBFactory.createDataset(directory);
>              tdbDataSet.begin(ReadWrite.WRITE);
>              model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
>              this.ontModel = ModelFactory.createOntologyModel(OntModelSpec.
> OWL_MEM, model);
>              tdbDataSet.commit();
>               firstInit=false;
>           } else {
>                tdbDataSet = TDBFactory.createDataset(directory);
>                tdbDataSet.begin(ReadWrite.WRITE);
>                model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
>                tdbDataSet.commit();
>          }
>
>        } catch (Exception e) {
>            e.printStackTrace();
>            throw new MDDException(String.format("Cannot access %s:%s",
> directory, e.getMessage()));
>        }
>        connected = true;
>     }
>
>     @Override
>     public void begin(boolean setAutoCommitTag) throws MDDException {
>        dbDataSet.begin(ReadWrite.WRITE) ;
>        transactionStarted = true;
>     }
>
>     @Override
>     public void commit() throws MDDException {
>        transactionStarted = false;
>        tdbDataSet.commit();
>     }
>
>     @Override
>     public void rollback() throws MDDException {
>        this.tdbDataSet.abort();
>        transactionStarted = false;
>     }
>
>    @Override
>     public void close() throws MDDException {
>        tdbDataSet.end();
>     }
>
> }
>
>
> On Mon, Sep 30, 2013 at 1:37 PM, Andy Seaborne <an...@apache.org> wrote:
>
>> On 28/09/13 23:46, Andreas Grünwald wrote:
>>
>>> Hello,
>>> I am trying to implement proper transaction handling based on the latest
>>> Jena TDB version.
>>>
>>> This is how I roughly initialize the model entities (I work with Jena's
>>> OntModel):
>>>
>>> class ConnectorWrapper
>>>      public void init() {
>>>         Dataset tdbDataSet = TDBFactory.createDataset(**directory);
>>>         model = tdbDataSet.getNamedModel(this.**getOntologySchemaIRI());
>>>          this.ontModel = ModelFactory.**createOntologyModel(**
>>> OntModelSpec.OWL_MEM,
>>> model);
>>>      }
>>> }
>>>
>>> I ran into some problems.
>>>
>>>      1. tdbDataSet.abort() is not working for me. As far as I got from the
>>>
>>>      documentation, the OwlModel does not support transactions. Did I got
>>> that
>>>      correct? Is there any kind of workaround?
>>>
>>
>> Perform the transaction on the tdbDataSet.
>>
>> Get the model inside the dataset.
>>
>>       2. How do I properly close/destroy a Jena Dataset? I am running into
>>> the
>>>
>>>      situation that I have several "Connector" instances (within one
>>> Thread),
>>>      which wrap an instance of the Jena Dataset. However, only the first
>>>      initialization succeeds, for the latter I get something like
>>> "transaction
>>>      is not active". I also get some errors in the command line "ERROR
>>>      com.hp.hpl.jena.tdb.**transaction.BlockMgrJournal - **** Not active:
>>> 1"
>>>      although I call "tdbDataSet.close() and tdbDataSet.end()" before
>>> calling
>>>      init() again. Is TDBFactory.createDataset(**directory) the correct
>>> way to
>>>      retrieve a dataset-instance, or should I call another method? Does my
>>>      initialization approach seem ok?
>>>
>>
>> Yes - use TDBFactory.createDataset(**directory), or have a single
>> variable for the object and initialize once.
>>
>> Don't bother closing it - when transactional, close is meaningless (and
>> harmless).
>>
>> Note that one thread can only have one transaction active.
>>
>> If that is not working, please could you provide a complete, minimal
>> example as the details matter here.
>>
>>          Andy
>>
>>
>>
>>> Thank you very much and best regards,
>>> Andreas
>>>
>>>
>>
>
>


Re: Jena TDB and Transactions ?

Posted by Andreas Grünwald <a....@gmail.com>.
Thanks for your response.
Actually I am applying the transaction on the tdbDataSet, from which I
derived the ontmodel. I am performing some changes on the ontModel, and
then try to abort the transaction with tdbDataSet.abort(). However, the
changes applied to the ontmodel are already persisted and cannot be undone
as it seems.

Here is the unit test which fails:

@Test
public void testInsertIndividualButRollback() throws MDDException {
   String reqId = "req777";
   JenaTDBConnection c = new JenaTDBConnection(connection data...);
   c.connect();
   c.begin();

   OntModel ont = c.getOntologyModel();
   String ns = c.getOntologySchemaIRI() + "#";
   OntClass requirement = ont.getOntClass(ns + "Requirement");
   OntProperty p = ont.getOntProperty(ns + "hasRequirementName");
   DatatypeProperty pd = ont.getDatatypeProperty(ns + "hasRequirementName");
//don't know yet which one is correct
   Individual req1 = ont.createIndividual(ns + name, requirement);
   req1.addProperty(pd, "individual requirement named 1");

   c.rollback();
   c.close();

   c.connect();
   c.begin();
   Individual reqBack =
c.getOntologyModel().getIndividual(c.getOntologySchemaIRI()
+ "#" + reqId);
   c.rollback();
   c.close();

   *assertTrue(reqBack == null);*
}

and the related Jena connection wrapper:


public class JenaTDBConnection {

   ...

   ...

   @Override
   public void connect() throws MDDException {
      modelSpec = createModelSpec();
      modelSpec.getDocumentManager().setProcessImports(false); //avoid
reading urls, such as http://www.itpm...
      String directory = this.host + "/" + this.schema;

      try {
         if(firstInit) {
            tdbDataSet = TDBFactory.createDataset(directory);
            tdbDataSet.begin(ReadWrite.WRITE);
            model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
            this.ontModel = ModelFactory.createOntologyModel(OntModelSpec.
OWL_MEM, model);
            tdbDataSet.commit();
             firstInit=false;
         } else {
              tdbDataSet = TDBFactory.createDataset(directory);
              tdbDataSet.begin(ReadWrite.WRITE);
              model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
              tdbDataSet.commit();
        }

      } catch (Exception e) {
          e.printStackTrace();
          throw new MDDException(String.format("Cannot access %s:%s",
directory, e.getMessage()));
      }
      connected = true;
   }

   @Override
   public void begin(boolean setAutoCommitTag) throws MDDException {
      dbDataSet.begin(ReadWrite.WRITE) ;
      transactionStarted = true;
   }

   @Override
   public void commit() throws MDDException {
      transactionStarted = false;
      tdbDataSet.commit();
   }

   @Override
   public void rollback() throws MDDException {
      this.tdbDataSet.abort();
      transactionStarted = false;
   }

  @Override
   public void close() throws MDDException {
      tdbDataSet.end();
   }

}


On Mon, Sep 30, 2013 at 1:37 PM, Andy Seaborne <an...@apache.org> wrote:

> On 28/09/13 23:46, Andreas Grünwald wrote:
>
>> Hello,
>> I am trying to implement proper transaction handling based on the latest
>> Jena TDB version.
>>
>> This is how I roughly initialize the model entities (I work with Jena's
>> OntModel):
>>
>> class ConnectorWrapper
>>     public void init() {
>>        Dataset tdbDataSet = TDBFactory.createDataset(**directory);
>>        model = tdbDataSet.getNamedModel(this.**getOntologySchemaIRI());
>>         this.ontModel = ModelFactory.**createOntologyModel(**
>> OntModelSpec.OWL_MEM,
>> model);
>>     }
>> }
>>
>> I ran into some problems.
>>
>>     1. tdbDataSet.abort() is not working for me. As far as I got from the
>>
>>     documentation, the OwlModel does not support transactions. Did I got
>> that
>>     correct? Is there any kind of workaround?
>>
>
> Perform the transaction on the tdbDataSet.
>
> Get the model inside the dataset.
>
>      2. How do I properly close/destroy a Jena Dataset? I am running into
>> the
>>
>>     situation that I have several "Connector" instances (within one
>> Thread),
>>     which wrap an instance of the Jena Dataset. However, only the first
>>     initialization succeeds, for the latter I get something like
>> "transaction
>>     is not active". I also get some errors in the command line "ERROR
>>     com.hp.hpl.jena.tdb.**transaction.BlockMgrJournal - **** Not active:
>> 1"
>>     although I call "tdbDataSet.close() and tdbDataSet.end()" before
>> calling
>>     init() again. Is TDBFactory.createDataset(**directory) the correct
>> way to
>>     retrieve a dataset-instance, or should I call another method? Does my
>>     initialization approach seem ok?
>>
>
> Yes - use TDBFactory.createDataset(**directory), or have a single
> variable for the object and initialize once.
>
> Don't bother closing it - when transactional, close is meaningless (and
> harmless).
>
> Note that one thread can only have one transaction active.
>
> If that is not working, please could you provide a complete, minimal
> example as the details matter here.
>
>         Andy
>
>
>
>> Thank you very much and best regards,
>> Andreas
>>
>>
>


-- 
Andreas Grünwald
Tel.: +43 650 77 82340

Re: Jena TDB and Transactions ?

Posted by Andy Seaborne <an...@apache.org>.
On 28/09/13 23:46, Andreas Grünwald wrote:
> Hello,
> I am trying to implement proper transaction handling based on the latest
> Jena TDB version.
>
> This is how I roughly initialize the model entities (I work with Jena's
> OntModel):
>
> class ConnectorWrapper
>     public void init() {
>        Dataset tdbDataSet = TDBFactory.createDataset(directory);
>        model = tdbDataSet.getNamedModel(this.getOntologySchemaIRI());
>         this.ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
> model);
>     }
> }
>
> I ran into some problems.
>
>     1. tdbDataSet.abort() is not working for me. As far as I got from the
>     documentation, the OwlModel does not support transactions. Did I got that
>     correct? Is there any kind of workaround?

Perform the transaction on the tdbDataSet.

Get the model inside the dataset.

>     2. How do I properly close/destroy a Jena Dataset? I am running into the
>     situation that I have several "Connector" instances (within one Thread),
>     which wrap an instance of the Jena Dataset. However, only the first
>     initialization succeeds, for the latter I get something like "transaction
>     is not active". I also get some errors in the command line "ERROR
>     com.hp.hpl.jena.tdb.transaction.BlockMgrJournal - **** Not active: 1"
>     although I call "tdbDataSet.close() and tdbDataSet.end()" before calling
>     init() again. Is TDBFactory.createDataset(directory) the correct way to
>     retrieve a dataset-instance, or should I call another method? Does my
>     initialization approach seem ok?

Yes - use TDBFactory.createDataset(directory), or have a single variable 
for the object and initialize once.

Don't bother closing it - when transactional, close is meaningless (and 
harmless).

Note that one thread can only have one transaction active.

If that is not working, please could you provide a complete, minimal 
example as the details matter here.

	Andy

>
> Thank you very much and best regards,
> Andreas
>