You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Holger Knublauch <ho...@topquadrant.com> on 2021/09/07 02:44:12 UTC

Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Hi Andy,

with our current migration to Jena 4.1 we noticed this change

     https://issues.apache.org/jira/browse/JENA-2006

is affecting the way that we use TDB (in the "shared TDB aka XDB") mode.

Previously, all named graphs were storing their own prefixes, yet now 
there seems to be only one prefix mapping for all named graphs, which 
breaks the assumptions that we made on the Graph API until now.

We need to find a way to restore the old behavior. I drilled into the 
code for a few hours but feel stuck due to my limited understanding of 
how these pieces work together. So far I have introduced this class 
below to override the createPrefixMapping method:

public class GraphXDB extends GraphTxnTDB {

     public GraphXDB(DatasetGraphTransaction dataset, Node graphName) {
         super(dataset, graphName);
     }

     @Override
     protected PrefixMapping createPrefixMapping() {
         DatasetPrefixesTDB pm = getDatasetGraphTDB().getStoragePrefixes();
         GraphPrefixesProjection projection = new 
GraphPrefixesProjection(getGraphName().toString(), pm);
         return Prefixes.adapt(projection);
     }
}

and this looks OK in read mode but fails on writes with errors such as:

ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20

Stack:

Thread [qtp975404820-101] (Suspended (breakpoint at line 304 in 
BlockMgrJournal))
     owns: Transaction  (id=366)
     BlockMgrJournal.checkActive() line: 304
     BlockMgrJournal.commitPrepare(Transaction) line: 91
     Transaction.lambda$prepare$0(TransactionLifecycle) line: 289
     74738525.accept(Object) line: not available
     ArrayList<E>.forEach(Consumer<? super E>) line: 1541
Transaction.forAllComponents(Consumer<TransactionLifecycle>) line: 283
     Transaction.prepare() line: 289
     Transaction.writerPrepareCommit() line: 165
     Transaction.commit() line: 120
     DatasetGraphTxn.commit() line: 61
     DatasetGraphTransaction.commit() line: 216
     DatasetGraphTxnTracking(DatasetGraphWrapper).commit() line: 276
     DatasetGraphTxnTracking.commit() line: 41
     TxnX.exec(T, TxnType, Runnable) line: 164
     TxnX.executeWrite(T, Runnable) line: 204
     PrefixMappingTxn.removeNsPrefix(String) line: 41
     ModelCom.removeNsPrefix(String) line: 972

Would you have any hints on how to proceed and whether this is on the 
right track? In the worst case, I guess we could switch to a completely 
different storage mechanism for those per-graph prefixes and bypass TDB.

Thank you
Holger



Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Andy Seaborne <an...@apache.org>.

On 07/09/2021 12:33, Holger Knublauch wrote:
> Slightly related to this, I noticed that 
> PrefixMappingAdapter.uriToPrefix is very inefficient, doing a reverse 
> O(n) look-up.

It is not used for writing - the RIOT writers use a PrefixMap that is 
tuned for writing usage patterns. Reverse multi-lookup with delete 
revealing is both tricky and simply hides work elsewhere.

The adapter has a "works with anything implementation".

     Andy


Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Andy Seaborne <an...@apache.org>.
Adding a graph is a copy, of triples and of the prefixes.






The exception is datasets-map-link


On 13/09/2021 03:47, Holger Knublauch wrote:
> To be consistent, wouldn't this mean that as soon as a Graph is added to 
> a dataset, then it should adopt the dataset namespaces too? I am 
> thinking about operations such as when a GraphMem is added to a 
> DatasetGraph using addGraph. But this appears problematic, as Graphs 
> could logically be part of multiple datasets. From the documentation it 
> seems that someone could even add a TDB Graph to another Dataset. So why 
> should TDB behave different from other datasets?

TDB behaves like other datasets: TDB1, TDB2, TIM (Transaction In 
Memory), and the basic dataset implementation.

Adding a graph is a copy, of the triples and of the prefixes.

A dataset is isolated - if a graph is added, then there is a graph in 
the dataset and later altering the source graph does not affect the 
dataset contents.

This is the difference between DatasetFactory.create() and 
DatasetFactory.createGeneral.

Dataset-map-link is the exception.

It does not provide the isolation contract.

Its primary usage is to give a dataset view over graphs from any 
storage, or some derived graph. Jena rules being the prototypical example.

It is best used as read-only, or at least not with both graph and 
dataset updates mixed together. If a graph gets created in 
DatasetGraphMapLink it defaults to in-memory so can be lost which people 
run into from time to time.

DatasetFactory.create() could change to be TIM. It should not make a 
difference except MRSW becomes MR+SW.

Fuseki uses TIM when storing in memory. It takes an assembler to change 
that.

     Andy

> 
> Holger
> 
> 
> On 2021-09-10 6:37 am, Andy Seaborne wrote:
>>
>>
>> On 07/09/2021 12:33, Holger Knublauch wrote:
>>> Having said this, I honestly don't think the limitations of one 
>>> serialization should be enough to motivate such a drastic change to 
>>> how prefixes are managed in TDB. 
>>
>> It is not one serialization - it includes JSON-LD, where it looks like 
>> new work will include packages of graphs as a dataset. It also makes 
>> default union graph work properly and consistently. A dataset is a 
>> logical collection of data - shared prefixes makes sense and is 
>> natural for datasets read/write.
>>
>> TDB 1 and 2 are both have per-graph prefixes. Hardly drastic.
>>
>> TQ has its own proprietary graph combination and security layer which 
>> is not based or related to RDF datasets and it does not use Jena data 
>> access security. Using a single dataset to store many graphs of that 
>> graph combination system is local to TQ.
>>
>>> For example it means that if someone changes the prefixes in one 
>>> graph of the dataset, then she also changes the prefixes for all 
>>> others, even for graphs that are not supposed to be writable for her. 
>>> And then what would happen if two graphs are loaded and added from 
>>> turtle files where each declares "ex" prefix? All this sounds very 
>>> fragile and makes the use of such shared-prefixmapping datasets 
>>> rather limiting - the old design was working just fine.
>>
>> The triples are kept apart. The second prefix does not change the 
>> earlier data.
>>
>>     Andy

Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Holger Knublauch <ho...@topquadrant.com>.
To be consistent, wouldn't this mean that as soon as a Graph is added to 
a dataset, then it should adopt the dataset namespaces too? I am 
thinking about operations such as when a GraphMem is added to a 
DatasetGraph using addGraph. But this appears problematic, as Graphs 
could logically be part of multiple datasets. From the documentation it 
seems that someone could even add a TDB Graph to another Dataset. So why 
should TDB behave different from other datasets?

Holger


On 2021-09-10 6:37 am, Andy Seaborne wrote:
>
>
> On 07/09/2021 12:33, Holger Knublauch wrote:
>> Having said this, I honestly don't think the limitations of one 
>> serialization should be enough to motivate such a drastic change to 
>> how prefixes are managed in TDB. 
>
> It is not one serialization - it includes JSON-LD, where it looks like 
> new work will include packages of graphs as a dataset. It also makes 
> default union graph work properly and consistently. A dataset is a 
> logical collection of data - shared prefixes makes sense and is 
> natural for datasets read/write.
>
> TDB 1 and 2 are both have per-graph prefixes. Hardly drastic.
>
> TQ has its own proprietary graph combination and security layer which 
> is not based or related to RDF datasets and it does not use Jena data 
> access security. Using a single dataset to store many graphs of that 
> graph combination system is local to TQ.
>
>> For example it means that if someone changes the prefixes in one 
>> graph of the dataset, then she also changes the prefixes for all 
>> others, even for graphs that are not supposed to be writable for her. 
>> And then what would happen if two graphs are loaded and added from 
>> turtle files where each declares "ex" prefix? All this sounds very 
>> fragile and makes the use of such shared-prefixmapping datasets 
>> rather limiting - the old design was working just fine.
>
> The triples are kept apart. The second prefix does not change the 
> earlier data.
>
>     Andy

Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Andy Seaborne <an...@apache.org>.

On 07/09/2021 12:33, Holger Knublauch wrote:
> Having said this, I honestly don't think the limitations of one 
> serialization should be enough to motivate such a drastic change to how 
> prefixes are managed in TDB. 

It is not one serialization - it includes JSON-LD, where it looks like 
new work will include packages of graphs as a dataset. It also makes 
default union graph work properly and consistently. A dataset is a 
logical collection of data - shared prefixes makes sense and is natural 
for datasets read/write.

TDB 1 and 2 are both have per-graph prefixes. Hardly drastic.

TQ has its own proprietary graph combination and security layer which is 
not based or related to RDF datasets and it does not use Jena data 
access security. Using a single dataset to store many graphs of that 
graph combination system is local to TQ.

> For example it means that if someone 
> changes the prefixes in one graph of the dataset, then she also changes 
> the prefixes for all others, even for graphs that are not supposed to be 
> writable for her. And then what would happen if two graphs are loaded 
> and added from turtle files where each declares "ex" prefix? All this 
> sounds very fragile and makes the use of such shared-prefixmapping 
> datasets rather limiting - the old design was working just fine.

The triples are kept apart. The second prefix does not change the 
earlier data.

     Andy

Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Holger Knublauch <ho...@topquadrant.com>.
Hi Andy,

many thanks.

On 2021-09-07 9:11 pm, Andy Seaborne wrote:
> Hi Holger,
>
> I let TQ know this was happening when the JIRA was in progress.
Quite possibly. Too many things happen in parallel, sorry if I missed 
that one and didn't pay enough attention.
>
> The errors you see mean internal transaction state has passed across 
> transaction boundaries. DatasetGraphTransaction is the object class 
> that carries across transactions in TDB1. DatasetGraphTDB has a 
> lifetime of one transaction (and it is also the storage).
>
> createPrefixMapping creates a cached prefix map but the code has 
> "getDatasetGraphTDB" which is the transaction specific object.
>
> Try overriding getPrefixMapping() with that code, not 
> createPrefixMapping() as a quick solution to test the rest of your 
> architecture.
Yes, after a quick test, this seems to work better. I need to do more 
testing tomorrow and check performance impact of creating this repeatedly.
>
> TDB1 uses PrefixMapTDB1/PrefixMapProxy to become switchable (a feature 
> that is native to TDB2).
>
> Beware about TriG based backups. They didn't separate prefixes per 
> graph before and still don't (with a different behaviour).  There 
> isn't a standard format for a setup that you describe.

Yes, we noticed the same issue. The work-around for us might be to add 
the prefix declarations as (temp) triples into each graph, e.g. using 
the sh:prefix vocabulary. But we are also adding alternative ways of 
doing backups, esp through Git integration where people use individual 
Turtle files. That's better anyway, as our Turtle writer preserves order 
of triples.

Having said this, I honestly don't think the limitations of one 
serialization should be enough to motivate such a drastic change to how 
prefixes are managed in TDB. For example it means that if someone 
changes the prefixes in one graph of the dataset, then she also changes 
the prefixes for all others, even for graphs that are not supposed to be 
writable for her. And then what would happen if two graphs are loaded 
and added from turtle files where each declares "ex" prefix? All this 
sounds very fragile and makes the use of such shared-prefixmapping 
datasets rather limiting - the old design was working just fine.

Anyway, as long as we can work around this...

Slightly related to this, I noticed that 
PrefixMappingAdapter.uriToPrefix is very inefficient, doing a reverse 
O(n) look-up.

>
>     Andy
>
> Would it be possible to have browsable stack traces next time? 
> Something to drop into the Eclipse stack viewer.

Will try, yes.

Thanks again,
Holger


>
> On 07/09/2021 03:44, Holger Knublauch wrote:
>> Hi Andy,
>>
>> with our current migration to Jena 4.1 we noticed this change
>>
>>      https://issues.apache.org/jira/browse/JENA-2006
>>
>> is affecting the way that we use TDB (in the "shared TDB aka XDB") mode.
>>
>> Previously, all named graphs were storing their own prefixes, yet now 
>> there seems to be only one prefix mapping for all named graphs, which 
>> breaks the assumptions that we made on the Graph API until now.
>>
>> We need to find a way to restore the old behavior. I drilled into the 
>> code for a few hours but feel stuck due to my limited understanding 
>> of how these pieces work together. So far I have introduced this 
>> class below to override the createPrefixMapping method:
>>
>> public class GraphXDB extends GraphTxnTDB {
>>
>>      public GraphXDB(DatasetGraphTransaction dataset, Node graphName) {
>>          super(dataset, graphName);
>>      }
>>
>>      @Override
>>      protected PrefixMapping createPrefixMapping() {
>>          DatasetPrefixesTDB pm = 
>> getDatasetGraphTDB().getStoragePrefixes();
>>          GraphPrefixesProjection projection = new 
>> GraphPrefixesProjection(getGraphName().toString(), pm);
>>          return Prefixes.adapt(projection);
>>      }
>> }
>>
>> and this looks OK in read mode but fails on writes with errors such as:
>>
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
>> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
>>
>> Stack:
>>
>> Thread [qtp975404820-101] (Suspended (breakpoint at line 304 in 
>> BlockMgrJournal))
>>      owns: Transaction  (id=366)
>>      BlockMgrJournal.checkActive() line: 304
>>      BlockMgrJournal.commitPrepare(Transaction) line: 91
>>      Transaction.lambda$prepare$0(TransactionLifecycle) line: 289
>>      74738525.accept(Object) line: not available
>>      ArrayList<E>.forEach(Consumer<? super E>) line: 1541
>> Transaction.forAllComponents(Consumer<TransactionLifecycle>) line: 283
>>      Transaction.prepare() line: 289
>>      Transaction.writerPrepareCommit() line: 165
>>      Transaction.commit() line: 120
>>      DatasetGraphTxn.commit() line: 61
>>      DatasetGraphTransaction.commit() line: 216
>>      DatasetGraphTxnTracking(DatasetGraphWrapper).commit() line: 276
>>      DatasetGraphTxnTracking.commit() line: 41
>>      TxnX.exec(T, TxnType, Runnable) line: 164
>>      TxnX.executeWrite(T, Runnable) line: 204
>>      PrefixMappingTxn.removeNsPrefix(String) line: 41
>>      ModelCom.removeNsPrefix(String) line: 972
>>
>> Would you have any hints on how to proceed and whether this is on the 
>> right track? In the worst case, I guess we could switch to a 
>> completely different storage mechanism for those per-graph prefixes 
>> and bypass TDB.
>>
>> Thank you
>> Holger
>>
>>

Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Andy Seaborne <an...@apache.org>.
Hi Holger,

I let TQ know this was happening when the JIRA was in progress.

The errors you see mean internal transaction state has passed across 
transaction boundaries. DatasetGraphTransaction is the object class that 
carries across transactions in TDB1. DatasetGraphTDB has a lifetime of 
one transaction (and it is also the storage).

createPrefixMapping creates a cached prefix map but the code has 
"getDatasetGraphTDB" which is the transaction specific object.

Try overriding getPrefixMapping() with that code, not 
createPrefixMapping() as a quick solution to test the rest of your 
architecture.

TDB1 uses PrefixMapTDB1/PrefixMapProxy to become switchable (a feature 
that is native to TDB2).

Beware about TriG based backups. They didn't separate prefixes per graph 
before and still don't (with a different behaviour).  There isn't a 
standard format for a setup that you describe.

     Andy

Would it be possible to have browsable stack traces next time? Something 
to drop into the Eclipse stack viewer.

On 07/09/2021 03:44, Holger Knublauch wrote:
> Hi Andy,
> 
> with our current migration to Jena 4.1 we noticed this change
> 
>      https://issues.apache.org/jira/browse/JENA-2006
> 
> is affecting the way that we use TDB (in the "shared TDB aka XDB") mode.
> 
> Previously, all named graphs were storing their own prefixes, yet now 
> there seems to be only one prefix mapping for all named graphs, which 
> breaks the assumptions that we made on the Graph API until now.
> 
> We need to find a way to restore the old behavior. I drilled into the 
> code for a few hours but feel stuck due to my limited understanding of 
> how these pieces work together. So far I have introduced this class 
> below to override the createPrefixMapping method:
> 
> public class GraphXDB extends GraphTxnTDB {
> 
>      public GraphXDB(DatasetGraphTransaction dataset, Node graphName) {
>          super(dataset, graphName);
>      }
> 
>      @Override
>      protected PrefixMapping createPrefixMapping() {
>          DatasetPrefixesTDB pm = getDatasetGraphTDB().getStoragePrefixes();
>          GraphPrefixesProjection projection = new 
> GraphPrefixesProjection(getGraphName().toString(), pm);
>          return Prefixes.adapt(projection);
>      }
> }
> 
> and this looks OK in read mode but fails on writes with errors such as:
> 
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
> 
> Stack:
> 
> Thread [qtp975404820-101] (Suspended (breakpoint at line 304 in 
> BlockMgrJournal))
>      owns: Transaction  (id=366)
>      BlockMgrJournal.checkActive() line: 304
>      BlockMgrJournal.commitPrepare(Transaction) line: 91
>      Transaction.lambda$prepare$0(TransactionLifecycle) line: 289
>      74738525.accept(Object) line: not available
>      ArrayList<E>.forEach(Consumer<? super E>) line: 1541
> Transaction.forAllComponents(Consumer<TransactionLifecycle>) line: 283
>      Transaction.prepare() line: 289
>      Transaction.writerPrepareCommit() line: 165
>      Transaction.commit() line: 120
>      DatasetGraphTxn.commit() line: 61
>      DatasetGraphTransaction.commit() line: 216
>      DatasetGraphTxnTracking(DatasetGraphWrapper).commit() line: 276
>      DatasetGraphTxnTracking.commit() line: 41
>      TxnX.exec(T, TxnType, Runnable) line: 164
>      TxnX.executeWrite(T, Runnable) line: 204
>      PrefixMappingTxn.removeNsPrefix(String) line: 41
>      ModelCom.removeNsPrefix(String) line: 972
> 
> Would you have any hints on how to proceed and whether this is on the 
> right track? In the worst case, I guess we could switch to a completely 
> different storage mechanism for those per-graph prefixes and bypass TDB.
> 
> Thank you
> Holger
> 
> 

Re: Shared prefixes for all named graphs in TDB dataset (JENA-2006)

Posted by Holger Knublauch <ho...@topquadrant.com>.
Small correction to stack trace from previous email, in case that matters:

Thread [qtp975404820-93] (Suspended (breakpoint at line 305 in 
BlockMgrJournal))
     owns: NodeTableNative  (id=586)
     owns: DatasetPrefixesTDB  (id=587)
     BlockMgrJournal.checkActive() line: 305
     BlockMgrJournal._promote(Block) line: 220
     BlockMgrJournal.promote(Block) line: 215
     BPTreeRecordsMgr(PageBlockMgr<T>).promote(Page) line: 109
     BPTreeRecords.promote() line: 118
     BPTreeRecords.internalInsert(Record) line: 129
     BPTreeNode.internalInsert(Record) line: 462
     BPTreeNode.insert(BPTreeNode, Record) line: 206
     BPlusTree.addAndReturnOld(Record) line: 323
     BPlusTree.add(Record) line: 315
     NodeTableNative.accessIndex(Node, boolean) line: 154
     NodeTableNative._idForNode(Node, boolean) line: 120
     NodeTableNative.getAllocateNodeId(Node) line: 76
     NodeTableInline(NodeTableWrapper).getAllocateNodeId(Node) line: 39
     NodeTableInline.getAllocateNodeId(Node) line: 50
     NodeTupleTableConcrete.addRow(Node...) line: 85
     DatasetPrefixesTDB.insertPrefix(String, String, String) line: 52
     GraphPrefixesProjection.add(String, String) line: 63
     PrefixMappingAdapter.add(String, String) line: 50
     PrefixMappingAdapter(PrefixMappingBase).setNsPrefix(String, String) 
line: 124
     PrefixMappingTxn.lambda$0(String, String) line: 35
     2012881121.run() line: not available
     TxnX.exec(T, TxnType, Runnable) line: 156
     TxnX.executeWrite(T, Runnable) line: 204
     PrefixMappingTxn.setNsPrefix(String, String) line: 35
     ModelCom.setNsPrefix(String, String) line: 965

On 2021-09-07 12:44 pm, Holger Knublauch wrote:
> Hi Andy,
>
> with our current migration to Jena 4.1 we noticed this change
>
>     https://issues.apache.org/jira/browse/JENA-2006
>
> is affecting the way that we use TDB (in the "shared TDB aka XDB") mode.
>
> Previously, all named graphs were storing their own prefixes, yet now 
> there seems to be only one prefix mapping for all named graphs, which 
> breaks the assumptions that we made on the Graph API until now.
>
> We need to find a way to restore the old behavior. I drilled into the 
> code for a few hours but feel stuck due to my limited understanding of 
> how these pieces work together. So far I have introduced this class 
> below to override the createPrefixMapping method:
>
> public class GraphXDB extends GraphTxnTDB {
>
>     public GraphXDB(DatasetGraphTransaction dataset, Node graphName) {
>         super(dataset, graphName);
>     }
>
>     @Override
>     protected PrefixMapping createPrefixMapping() {
>         DatasetPrefixesTDB pm = 
> getDatasetGraphTDB().getStoragePrefixes();
>         GraphPrefixesProjection projection = new 
> GraphPrefixesProjection(getGraphName().toString(), pm);
>         return Prefixes.adapt(projection);
>     }
> }
>
> and this looks OK in read mode but fails on writes with errors such as:
>
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] Not active: 20
> ERROR o.a.j.t.t.BlockMgrJournal [qtp975404820-67] **** Not active: 20
>
> Stack:
>
> Thread [qtp975404820-101] (Suspended (breakpoint at line 304 in 
> BlockMgrJournal))
>     owns: Transaction  (id=366)
>     BlockMgrJournal.checkActive() line: 304
>     BlockMgrJournal.commitPrepare(Transaction) line: 91
>     Transaction.lambda$prepare$0(TransactionLifecycle) line: 289
>     74738525.accept(Object) line: not available
>     ArrayList<E>.forEach(Consumer<? super E>) line: 1541
> Transaction.forAllComponents(Consumer<TransactionLifecycle>) line: 283
>     Transaction.prepare() line: 289
>     Transaction.writerPrepareCommit() line: 165
>     Transaction.commit() line: 120
>     DatasetGraphTxn.commit() line: 61
>     DatasetGraphTransaction.commit() line: 216
>     DatasetGraphTxnTracking(DatasetGraphWrapper).commit() line: 276
>     DatasetGraphTxnTracking.commit() line: 41
>     TxnX.exec(T, TxnType, Runnable) line: 164
>     TxnX.executeWrite(T, Runnable) line: 204
>     PrefixMappingTxn.removeNsPrefix(String) line: 41
>     ModelCom.removeNsPrefix(String) line: 972
>
> Would you have any hints on how to proceed and whether this is on the 
> right track? In the worst case, I guess we could switch to a 
> completely different storage mechanism for those per-graph prefixes 
> and bypass TDB.
>
> Thank you
> Holger
>
>