You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2017/10/03 19:34:14 UTC

[28/65] [abbrv] jena git commit: JENA-1397: Rename java packages

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/bplustree/soak/CmdTestBPlusTreeRewriter.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/bplustree/soak/CmdTestBPlusTreeRewriter.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/bplustree/soak/CmdTestBPlusTreeRewriter.java
deleted file mode 100644
index db8ed93..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/bplustree/soak/CmdTestBPlusTreeRewriter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.bplustree.soak;
-
-import org.seaborne.dboe.base.record.RecordFactory ;
-import org.seaborne.dboe.index.test.BaseSoakTest ;
-import org.seaborne.dboe.sys.SystemIndex ;
-import org.seaborne.dboe.trans.bplustree.BPT ;
-import org.seaborne.dboe.trans.bplustree.rewriter.TestBPlusTreeRewriterNonTxn ;
-
-public class CmdTestBPlusTreeRewriter extends BaseSoakTest
-{
-    static public void main(String... argv) {
-        new CmdTestBPlusTreeRewriter(argv).mainRun() ;
-    }
-
-    protected CmdTestBPlusTreeRewriter(String[] argv) {
-        super(argv) ;
-    }
-    
-    static int KeySize     = 4 ;
-    static int ValueSize   = 8 ;
-    
-    @Override
-    protected void before() {
-        SystemIndex.setNullOut(true) ;
-        // Forced mode
-        if ( false ) {
-            BPT.forcePromoteModes = true ;
-            BPT.promoteDuplicateNodes = true ;
-            BPT.promoteDuplicateRecords  = true ;
-        }
-        if ( false ) {
-            // Transactions.
-        }
-    }
-    
-    @Override
-    protected void after() { }
-
-    @Override
-    protected void runOneTest(int testCount, int order, int size, boolean debug) {
-        runOneTest(testCount, order, size) ;
-    }
-
-    @Override
-    protected void runOneTest(int testCount, int order, int size) {
-        RecordFactory recordFactory = new RecordFactory(KeySize, ValueSize) ;
-        TestBPlusTreeRewriterNonTxn.runOneTest(order, size, recordFactory, false) ;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TS_TransData.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TS_TransData.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TS_TransData.java
deleted file mode 100644
index 9dddece..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TS_TransData.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import org.junit.runner.RunWith ;
-import org.junit.runners.Suite ;
-import org.junit.runners.Suite.SuiteClasses ;
-
-@RunWith(Suite.class)
-@SuiteClasses( {
-    TestTransIndexMem.class
-    , TestTransBlob.class
-    , TestTransBlobPersistent.class
-    , TestTransBinaryDataFileGeneral.class
-    , TestTransBinaryDataFile.class
-})
-
-public class TS_TransData { }
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFile.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFile.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFile.java
deleted file mode 100644
index 462ec36..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFile.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import org.apache.jena.atlas.lib.Bytes ;
-import org.apache.jena.atlas.lib.StrUtils ;
-import org.junit.After ;
-import org.junit.Before ;
-import org.junit.Test ;
-import org.seaborne.dboe.base.file.* ;
-import org.seaborne.dboe.jenax.Txn ;
-import org.seaborne.dboe.transaction.ThreadTxn ;
-import org.seaborne.dboe.transaction.Transactional ;
-import org.seaborne.dboe.transaction.TransactionalFactory ;
-import org.seaborne.dboe.transaction.txn.ComponentId ;
-import org.seaborne.dboe.transaction.txn.journal.Journal ;
-
-
-public class TestTransBinaryDataFile {
-    private Journal journal ;
-    private BinaryDataFile baseBinData ;
-    private TransBinaryDataFile transBinData ;
-    private Transactional transactional ;
-    
-    @Before public void before() {
-        // XXX Builder.
-        journal = Journal.create(Location.mem()) ;
-        baseBinData = new BinaryDataFileMem() ;
-        BufferChannel chan = FileFactory.createBufferChannelMem() ;
-        ComponentId cid = ComponentId.allocLocal() ;
-        transBinData = new TransBinaryDataFile(baseBinData, cid, chan) ;
-        transBinData.open();
-        transactional = TransactionalFactory.createTransactional(journal, transBinData) ;    
-    }
-
-    @After public void after() { }
-    
-//    private static ByteBuffer str2bb(String x) {
-//        byte[] d = StrUtils.asUTF8bytes(x) ;
-//        ByteBuffer bb = ByteBuffer.wrap(d) ;
-//        return bb ;
-//    }
-    
-    private static long writeOne(Transactional transactional, TransBinaryDataFile transBinaryFile, String data) {
-        return 
-            Txn.calculateWrite(transactional, ()->{
-                byte[] bytes = StrUtils.asUTF8bytes(data) ;
-                int len = bytes.length ;
-                byte[] lenBytes = new byte[4] ;
-                Bytes.setInt(len, lenBytes);
-                // To work with strings, we write length,bytes.
-                long x = transBinaryFile.write(lenBytes);
-                transBinaryFile.write(bytes);
-                return x ;
-        }) ;
-    }
-    
-    private static String readOne(Transactional transactional, TransBinaryDataFile transBinaryFile, long posn) {
-        return Txn.calculateRead(transactional, ()->{
-            byte[] lenBytes = new byte[4] ;
-            long x = posn ;
-            int got = transBinaryFile.read(x, lenBytes) ;
-            x += got ;
-            
-            int len = Bytes.getInt(lenBytes) ;
-            byte[] bytes = new byte[len] ;
-            got = transBinaryFile.read(x, bytes) ;
-            x += got ;
-            return StrUtils.fromUTF8bytes(bytes) ;
-        }) ;
-    }
-    
-    @Test public void transObjectFile_str1() {
-        String str = "Hello World" ; 
-        long x = writeOne(transactional, transBinData, str) ;
-        String str2 = readOne(transactional, transBinData, x) ;
-        assertEquals(str, str2) ;
-    }
-
-    @Test public void transObjectFile_str2() {
-        String str1 = "" ; 
-        String str2 = "$" ; 
-        long x1 = writeOne(transactional, transBinData, str1) ;
-        long x2 = writeOne(transactional, transBinData, str2) ;
-        assertNotEquals("("+x1+","+x2+")", x1, x2) ;
-        
-        String out2 = readOne(transactional, transBinData, x2) ;
-        String out1 = readOne(transactional, transBinData, x1) ;
-        assertEquals(str1, out1) ;
-        assertEquals(str2, out2) ;
-    }
-
-    static byte[] bytes0 = new byte[0] ;
-    static int len0 = 0 ;
-    
-    static byte[] bytes1 = new byte[] {(byte)1,(byte)2,(byte)3} ;
-    static int len1 = bytes1.length ;
-    
-    static byte[] bytes2 = StrUtils.asUTF8bytes("TheNext") ;
-    static int len2 = bytes2.length ;
-
-
-    @Test public void transObjectFile_1() {
-        Txn.executeWrite(transactional, ()->{
-            long x = transBinData.write(bytes1) ;
-            assertEquals(0L, x) ;
-            assertEquals(len1, transBinData.length()) ;
-        }) ;
-    }
-    
-    @Test public void transObjectFile_2() {
-        Txn.executeWrite(transactional, ()->{
-            long x = transBinData.write(bytes1) ;
-            assertEquals(0L, x) ;
-            assertEquals(len1, transBinData.length()) ;
-            byte[] bytes1a = new byte[len1] ;  
-            int len = transBinData.read(0, bytes1a) ;
-            assertEquals(len1, len) ;
-            assertArrayEquals(bytes1, bytes1a);
-        }) ;
-    }
-
-    @Test public void transObjectFile_3() {
-        Txn.executeWrite(transactional, ()->{
-            long x1 = transBinData.write(bytes1) ;
-            long x2 = transBinData.write(bytes2) ;
-            byte[] bytes1a = new byte[len1] ;  
-            byte[] bytes2a = new byte[len2] ;
-            int len1a = transBinData.read(0, bytes1a) ;
-            int len2a = transBinData.read(len1a, bytes2a) ;
-            assertEquals(len1, len1a) ;
-            assertArrayEquals(bytes1, bytes1a);
-            assertEquals(len2, len2a) ;
-            assertArrayEquals(bytes2, bytes2a);
-        }) ;
-    }
-
-    @Test public void transObjectFile_4() {
-        Txn.executeWrite(transactional, ()->{
-            long x1 = transBinData.write(bytes1) ;
-            long x2 = transBinData.write(bytes2) ;
-        }) ;
-        Txn.executeRead(transactional, ()->{
-            byte[] bytes1a = new byte[len1] ;  
-            byte[] bytes2a = new byte[len2] ;
-            int len1a = transBinData.read(0, bytes1a) ;
-            int len2a = transBinData.read(len1a, bytes2a) ;
-            assertEquals(len1, len1a) ;
-            assertArrayEquals(bytes1, bytes1a);
-            assertEquals(len2, len2a) ;
-            assertArrayEquals(bytes2, bytes2a);
-        }) ;
-    }
-    
-    // As above but reverse the read order
-    @Test public void transObjectFile_5() {
-        Txn.executeWrite(transactional, ()->{
-            long x1 = transBinData.write(bytes1) ;
-            long x2 = transBinData.write(bytes2) ;
-        }) ;
-        Txn.executeRead(transactional, ()->{
-            byte[] bytes1a = new byte[len1] ;  
-            byte[] bytes2a = new byte[len2] ;
-            
-            int len2a = transBinData.read(len1, bytes2a) ;
-            int len1a = transBinData.read(0, bytes1a) ;
-            
-            assertEquals(len1, len1a) ;
-            assertArrayEquals(bytes1, bytes1a);
-            assertEquals(len2, len2a) ;
-            assertArrayEquals(bytes2, bytes2a);
-        }) ;
-    }
-
-
-    @Test public void transObjectFile_6() {
-        Txn.executeWrite(transactional, ()->{
-            long x1 = transBinData.write(bytes1) ;
-            long x2 = transBinData.write(bytes2) ;
-        }) ;
-        Txn.executeRead(transactional, ()->{
-            byte[] bytes2a = new byte[len2] ;
-            int len2a = transBinData.read(len1, bytes2a) ;
-            assertEquals(len2, len2a) ;
-            assertArrayEquals(bytes2, bytes2a);
-        }) ;
-    }
-    
-    @Test public void transObjectFile_7() {
-        ThreadTxn.threadTxnWriteAbort(transactional, ()->{
-            long x1 = transBinData.write(bytes1) ;
-        }) ;
-        
-        Txn.executeRead(transactional, ()->{
-            assertEquals(0L, transBinData.length()) ;
-        }) ;
-    }
-
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFileGeneral.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFileGeneral.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFileGeneral.java
deleted file mode 100644
index 1a777d2..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBinaryDataFileGeneral.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import org.apache.jena.query.ReadWrite ;
-import org.seaborne.dboe.base.file.* ;
-import org.seaborne.dboe.transaction.Transactional ;
-import org.seaborne.dboe.transaction.TransactionalFactory ;
-import org.seaborne.dboe.transaction.txn.ComponentId ;
-import org.seaborne.dboe.transaction.txn.journal.Journal ;
-
-public class TestTransBinaryDataFileGeneral extends AbstractTestBinaryDataFile {
-    private Journal journal ;
-    private BinaryDataFile baseBinData ;
-    private TransBinaryDataFile transBinData ;
-    private Transactional transactional ;
-
-    @Override
-    protected BinaryDataFile createBinaryDataFile() {
-        // XXX Builder.
-        journal = Journal.create(Location.mem()) ;
-        baseBinData = new BinaryDataFileMem() ;
-        BufferChannel chan = FileFactory.createBufferChannelMem() ;
-        ComponentId cid = ComponentId.allocLocal() ;
-        transBinData = new TransBinaryDataFile(baseBinData, cid, chan) ;
-        transBinData.open();
-        transactional = TransactionalFactory.createTransactional(journal, transBinData) ;
-        //Non-transactional usage of a disposed file. 
-        transactional.begin(ReadWrite.WRITE) ;
-        return transBinData ; 
-        
-    }
-    
-    @Override
-    protected void releaseBinaryDataFile(BinaryDataFile file) {
-        if ( file.isOpen() ) {
-            transactional.commit() ;
-            transactional.end() ;
-            baseBinData.close() ;
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlob.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlob.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlob.java
deleted file mode 100644
index 77145bc..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlob.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import java.util.concurrent.atomic.AtomicReference ;
-
-import org.apache.jena.query.ReadWrite ;
-import org.junit.After ;
-import org.junit.Assert ;
-import org.junit.Before ;
-import org.junit.Test ;
-import org.seaborne.dboe.base.file.BufferChannel ;
-import org.seaborne.dboe.base.file.BufferChannelMem ;
-import org.seaborne.dboe.base.file.Location ;
-import org.seaborne.dboe.jenax.Txn ;
-import org.seaborne.dboe.transaction.ThreadTxn ;
-import org.seaborne.dboe.transaction.Transactional ;
-import org.seaborne.dboe.transaction.TransactionalFactory ;
-import org.seaborne.dboe.transaction.txn.ComponentId ;
-import org.seaborne.dboe.transaction.txn.journal.Journal ;
-
-public class TestTransBlob extends Assert {
-    private Journal         journal ;
-    private TransBlob       transBlob ;
-    private Transactional   transactional ;
-    
-    @Before public void before() {
-        journal = Journal.create(Location.mem()) ;
-        
-        BufferChannel chan = BufferChannelMem.create("TestTransBlob") ;
-        ComponentId cid = ComponentId.allocLocal() ;
-        transBlob = new TransBlob(cid, chan) ;
-        transactional = TransactionalFactory.createTransactional(journal, transBlob) ;    
-    }
-
-    @After public void after() { }
-    
-    public static void write(Transactional transactional, TransBlob transBlob, String data) {
-        Txn.executeWrite(transactional, ()->{
-            transBlob.setString(data);
-        }) ;
-    }
-    
-    public static String read(Transactional transactional, TransBlob transBlob) {
-        return Txn.calculateRead(transactional, ()->{
-            return transBlob.getString() ;
-        }) ;
-    }
-    
-    void threadRead(String expected) {
-        AtomicReference<String> result = new AtomicReference<>() ;
-        ThreadTxn.threadTxnRead(transactional, ()-> {
-            String s = transBlob.getString() ;
-            result.set(s);
-        }).run(); 
-        Assert.assertEquals(expected, result.get());
-    }
-    
-    // testing with real files in TestTransBlobPersistent
-    
-    @Test public void transBlob_1() {
-        String str = "Hello World" ; 
-        write(transactional, transBlob, str) ;
-        String str2 = read(transactional, transBlob) ;
-        assertEquals(str, str2) ;
-        String str3 = transBlob.getString() ;
-        assertEquals(str, str3) ;
-
-    }
-
-    // Verify visibility and transactions.
-    @Test public void transBlob_2() {
-        String str1 = "one" ; 
-        String str2 = "two" ;
-        write(transactional, transBlob, str1) ;
-        transactional.begin(ReadWrite.WRITE);
-        transBlob.setString(str2); 
-        
-        // Difefrent therad and transaction.
-        threadRead(str1) ;
-        
-        transactional.commit() ;
-        transactional.end() ;
-        threadRead(str2) ;
-    }
-    
-    // Verify visibility and transactions.
-    @Test public void transBlob_3() {
-        String str1 = "one" ; 
-        String str2 = "two" ;
-        write(transactional, transBlob, str1) ;
-        String s1 = transBlob.getString() ;
-        assertEquals(str1, s1) ;
-        String s2 = read(transactional, transBlob) ;
-        assertEquals(str1, s2) ;
-        
-        // Start now.
-        ThreadTxn tt = ThreadTxn.threadTxnRead(transactional, ()-> {
-            String sr = transBlob.getString() ;
-            Assert.assertEquals(str1, sr) ;
-        }) ;
-        
-        write(transactional, transBlob, str2) ;
-        
-        Txn.executeWrite(transactional, ()->{
-            transBlob.setString(str2) ; 
-            String s = transBlob.getString() ;
-            assertEquals(str2, s) ;
-        }) ;
-        // Run later, after W transaction.
-        tt.run();
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlobPersistent.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlobPersistent.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlobPersistent.java
deleted file mode 100644
index eda7c3c..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransBlobPersistent.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import org.apache.jena.util.FileUtils ;
-
-import org.apache.jena.atlas.lib.FileOps ;
-import org.junit.* ;
-import org.seaborne.dboe.base.file.BufferChannel ;
-import org.seaborne.dboe.base.file.BufferChannelFile ;
-import org.seaborne.dboe.base.file.Location ;
-import org.seaborne.dboe.jenax.Txn;
-import org.seaborne.dboe.transaction.Transactional ;
-import org.seaborne.dboe.transaction.TransactionalFactory ;
-import org.seaborne.dboe.transaction.txn.ComponentId ;
-import org.seaborne.dboe.transaction.txn.journal.Journal ;
-
-public class TestTransBlobPersistent extends Assert {
-    private final static String DIR  = "target/blobtest" ;
-    private final static String JRNL = DIR+"/journal.jrnl" ;
-    private final static String DATA = DIR+"/blob.data" ;
-    
-    @BeforeClass public static void beforeClass() {
-        FileOps.ensureDir(DIR);
-    }
-    
-    @Before public void before() {
-        FileOps.deleteSilent(JRNL) ;
-        FileOps.deleteSilent(DATA) ;
-    }
-    
-    @AfterClass public static void afterClass() {
-        FileOps.deleteSilent(JRNL) ;
-        FileOps.deleteSilent(DATA) ;
-    }
-    
-    @Test public void transBlobFile_1() throws Exception {
-        Journal journal = Journal.create(Location.create(DIR)) ;
-        BufferChannel chan = BufferChannelFile.create(DATA) ;
-        ComponentId cid = ComponentId.allocLocal() ;
-        TransBlob transBlob = new TransBlob(cid, chan) ;
-        Transactional transactional = TransactionalFactory.createTransactional(journal, transBlob) ;   
-        String str = "Hello" ; 
-
-        TestTransBlob.write(transactional, transBlob, str) ;
-        
-        chan.close() ;
-        journal.close() ;
-        String s = FileUtils.readWholeFileAsUTF8(DATA) ;
-        assertEquals(str, s); 
-    }
-
-    @Test public void transBlobFile_2() throws Exception {
-        Journal journal = Journal.create(Location.create(DIR)) ;
-        BufferChannel chan = BufferChannelFile.create(DATA) ;
-        ComponentId cid = ComponentId.allocLocal() ;
-        TransBlob transBlob = new TransBlob(cid, chan) ;
-        Transactional transactional = TransactionalFactory.createTransactional(journal, transBlob) ;   
-        String str = "Hello1" ; 
-
-        Txn.executeWrite(transactional, ()->{
-            transBlob.setString("one");
-        }) ;
-        
-        Txn.executeWrite(transactional, ()->{
-            transBlob.setString("two");
-        }) ;
-        
-        chan.close() ;
-        journal.close() ;
-        String s = FileUtils.readWholeFileAsUTF8(DATA) ;
-        assertEquals("two", s); 
-    }
-    
-    // restart.
-    @Test public void transBlobFile_3() throws Exception {
-        String str = "Hello World" ; 
-        // Write out.
-        {
-            Journal journal = Journal.create(Location.create(DIR)) ;
-            BufferChannel chan = BufferChannelFile.create(DATA) ;
-            ComponentId cid = ComponentId.allocLocal() ;
-            TransBlob transBlob = new TransBlob(cid, chan) ;
-            Transactional transactional = TransactionalFactory.createTransactional(journal, transBlob) ;   
-            TestTransBlob.write(transactional, transBlob, str) ;
-            chan.close();
-            journal.close(); 
-        }
-        // Restart
-        {
-            Journal journal = Journal.create(Location.create(DIR)) ;
-            BufferChannel chan = BufferChannelFile.create(DATA) ;
-            ComponentId cid = ComponentId.allocLocal() ;
-            TransBlob transBlob = new TransBlob(cid, chan) ;
-            Transactional transactional = TransactionalFactory.createTransactional(journal, transBlob) ;   
-            String s = TestTransBlob.read(transactional, transBlob) ;
-            assertEquals(str, s); 
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransIndexMem.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransIndexMem.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransIndexMem.java
deleted file mode 100644
index 6f140b7..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/data/TestTransIndexMem.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.data;
-
-import org.seaborne.dboe.base.record.RecordFactory ;
-import org.seaborne.dboe.index.Index ;
-import org.seaborne.dboe.index.IndexMap ;
-import org.seaborne.dboe.index.test.AbstractTestIndex ;
-
-public class TestTransIndexMem extends AbstractTestIndex
-{
-    @Override
-    protected Index makeIndex(int kLen, int vLen)
-    {
-        RecordFactory rf = new RecordFactory(kLen, vLen) ;
-        return new IndexMap(rf) ;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/recovery/TestRecovery.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/recovery/TestRecovery.java b/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/recovery/TestRecovery.java
deleted file mode 100644
index 22e7ace..0000000
--- a/jena-db/jena-dboe-trans-data/src/test/java/org/seaborne/dboe/trans/recovery/TestRecovery.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.seaborne.dboe.trans.recovery;
-
-import java.nio.ByteBuffer ;
-import java.util.Arrays ;
-
-import org.apache.jena.atlas.lib.FileOps ;
-import org.junit.* ;
-import org.seaborne.dboe.base.file.BufferChannel ;
-import org.seaborne.dboe.base.file.BufferChannelFile ;
-import org.seaborne.dboe.base.file.Location ;
-import org.seaborne.dboe.migrate.L ;
-import org.seaborne.dboe.trans.data.TransBlob ;
-import org.seaborne.dboe.transaction.txn.ComponentId ;
-import org.seaborne.dboe.transaction.txn.TransactionCoordinator ;
-import org.seaborne.dboe.transaction.txn.journal.Journal ;
-import org.seaborne.dboe.transaction.txn.journal.JournalEntry ;
-import org.seaborne.dboe.transaction.txn.journal.JournalEntryType ;
-
-// We need something to recover io order to test recovery.
-
-public class TestRecovery extends Assert {
-    private final static String DIR   = "target/recovery" ;
-    private final static String JRNL  = DIR + "/journal.jrnl" ;
-    private final static String DATA  = DIR + "/blob.data" ;
-    private final static String DATA1 = DIR + "/blob.data-1" ;
-    private final static String DATA2 = DIR + "/blob.data-2" ;
-
-    @BeforeClass public static void beforeClass() {
-        FileOps.ensureDir(DIR);
-    }
-    
-    @Before public void before() {
-        FileOps.deleteSilent(JRNL) ;
-        FileOps.deleteSilent(DATA) ;
-        FileOps.deleteSilent(DATA1) ;
-        FileOps.deleteSilent(DATA2) ;
-    }
-    
-    @AfterClass public static void afterClass() {
-        FileOps.deleteSilent(JRNL) ;
-        FileOps.deleteSilent(DATA) ;
-    }
-    
-    // Fake journal recovery.
-    @Test public void recoverBlobFile_1() throws Exception {
-        String str = "Hello Journal" ; 
-        ComponentId cid = ComponentId.allocLocal() ;
-//        ComponentIdRegistry registry = new ComponentIdRegistry() ;
-//        registry.register(cid, "Blob", 1) ;
-        
-        // Write out a journal.
-        {
-            Journal journal = Journal.create(Location.create(DIR)) ;
-            journal.write(JournalEntryType.REDO, cid, L.stringToByteBuffer(str)) ;
-            journal.writeJournal(JournalEntry.COMMIT) ;
-            journal.close(); 
-        }
-        
-        TransactionCoordinator coord = new TransactionCoordinator(Location.create(DIR)) ;
-        BufferChannel chan = BufferChannelFile.create(DATA) ;
-        TransBlob tBlob = new TransBlob(cid, chan) ;
-        coord.add(tBlob) ;
-        coord.start();
-        
-        ByteBuffer blob = tBlob.getBlob() ;
-        assertNotNull(blob); 
-        String s = L.byteBufferToString(blob) ;
-        assertEquals(str,s) ;
-        coord.shutdown();
-    }
-
-    @Test public void recoverBlobFile_2() throws Exception {
-        String str1 = "Recovery One" ; 
-        String str2 = "Recovery Two" ; 
-        ComponentId cid1 = ComponentId.allocLocal() ;
-        ComponentId cid2 = ComponentId.allocLocal() ;
-        
-        // Write out a journal for two components.
-        {
-            Journal journal = Journal.create(Location.create(DIR)) ;
-            journal.write(JournalEntryType.REDO, cid1, L.stringToByteBuffer(str1)) ;
-            journal.write(JournalEntryType.REDO, cid2, L.stringToByteBuffer(str2)) ;
-            journal.writeJournal(JournalEntry.COMMIT) ;
-            journal.close(); 
-        }
-        
-        Journal journal = Journal.create(Location.create(DIR)) ;
-        BufferChannel chan = BufferChannelFile.create(DATA) ;
-        TransBlob tBlob1 = new TransBlob(cid1, chan) ;
-        TransBlob tBlob2 = new TransBlob(cid2, chan) ;
-
-        TransactionCoordinator coord = new TransactionCoordinator(journal, Arrays.asList(tBlob1, tBlob2)) ;
-        coord.start();
-        
-        ByteBuffer blob1 = tBlob1.getBlob() ;
-        assertNotNull(blob1); 
-        String s1 = L.byteBufferToString(blob1) ;
-        assertEquals(str1,s1) ;
-        
-        ByteBuffer blob2 = tBlob2.getBlob() ;
-        assertNotNull(blob2); 
-        String s2 = L.byteBufferToString(blob2) ;
-        assertEquals(str2,s2) ;
-
-        assertNotEquals(str1,str2) ;
-        coord.shutdown();
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ComponentIdRegistry.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ComponentIdRegistry.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ComponentIdRegistry.java
new file mode 100644
index 0000000..0ff1620
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ComponentIdRegistry.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+
+
+public class ComponentIdRegistry {
+//    // Not stable across JVMs hence "local" 
+//    private ComponentId localCid = ComponentId.create("Local", L.uuidAsBytes(UUID.randomUUID())) ;
+//    
+//    // No! byte[].equals is Object.equals
+//    
+//    // ComponentId equality is by bytes (not display label)
+//    // so this maps bytes to a better form. 
+//    private Map<Holder, ComponentId> registry = new ConcurrentHashMap<>() ;
+//    
+//    public ComponentIdRegistry() { }
+//    
+//    public ComponentId registerLocal(String label, int index) {
+//        return register(localCid, label, index) ;
+//    }
+//    
+//    public ComponentId register(ComponentId base, String label, int index) {
+//        byte[] bytes = base.bytes() ;
+//        bytes = Arrays.copyOf(bytes, bytes.length) ;
+//        int x = Bytes.getInt(bytes, bytes.length - SystemBase.SizeOfInt) ;
+//        x = x ^ index ;
+//        Bytes.setInt(x, bytes, bytes.length-SystemBase.SizeOfInt) ;
+//        ComponentId cid = new ComponentId(label+"-"+index, bytes) ;
+//        Holder h = new Holder(bytes) ;
+//        registry.put(h, cid) ;
+//        return cid ;
+//    }
+//    
+//    public ComponentId lookup(byte[] bytes) {
+//        Holder h = new Holder(bytes) ;
+//        return registry.get(h) ;
+//    }
+//    
+//    public void reset() {
+//        registry.clear() ;
+//    }
+//    
+//    // Makes equality the value of the bytes. 
+//    static class Holder {
+//        private final byte[] bytes ;
+//
+//        Holder(byte[] bytes) { this.bytes = bytes ; }
+//
+//        @Override
+//        public int hashCode() {
+//            final int prime = 31 ;
+//            int result = 1 ;
+//            result = prime * result + Arrays.hashCode(bytes) ;
+//            return result ;
+//        }
+//
+//        @Override
+//        public boolean equals(Object obj) {
+//            if ( this == obj )
+//                return true ;
+//            if ( obj == null )
+//                return false ;
+//            if ( getClass() != obj.getClass() )
+//                return false ;
+//            Holder other = (Holder)obj ;
+//            if ( !Arrays.equals(bytes, other.bytes) )
+//                return false ;
+//            return true ;
+//        }
+//        
+//        @Override
+//        public String toString() {
+//            return Bytes.asHex(bytes) ;
+//        }
+//    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ThreadTxn.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ThreadTxn.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ThreadTxn.java
new file mode 100644
index 0000000..a8a92df
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/ThreadTxn.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import java.util.Objects ;
+import java.util.concurrent.Executor ;
+import java.util.concurrent.Semaphore ;
+import java.util.concurrent.atomic.AtomicReference ;
+
+import org.apache.jena.dboe.sys.Sys;
+import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.sparql.core.Transactional ;
+
+/**
+ * An action that will happen on a different thread later when {@link #run} is
+ * called. A thread is created and the transaction started during a call to the
+ * creation operations {@link #threadTxnRead} or {@link #threadTxnWrite}.
+ * The associated Runnable is called and the transaction completed when
+ * {@link #run} is called. Being on a thread, the state of the world the
+ * forked transaction sees is outside the creating thread which may itself be in a
+ * transaction. Warning: creating a write transaction inside a write transaction
+ * will cause deadlock.
+ */ 
+public class ThreadTxn {
+    
+    /** Create a thread-backed delayed READ transaction action. */
+    public static ThreadTxn threadTxnRead(Transactional trans, Runnable action) {
+        return ThreadTxn.create(trans, ReadWrite.READ, action, false) ;
+    }
+    
+    /** Create a thread-backed delayed WRITE  action.
+     * If called from inside a write transaction on the {@code trans},
+     * this will deadlock.
+     */
+    public static ThreadTxn threadTxnWrite(Transactional trans, Runnable action) {
+        return ThreadTxn.create(trans, ReadWrite.WRITE, action, true) ;
+    }
+    
+    /** Create a thread-backed delayed WRITE-abort action (testing). */
+    public static ThreadTxn threadTxnWriteAbort(Transactional trans, Runnable action) {
+        return ThreadTxn.create(trans, ReadWrite.WRITE, action, false) ;
+    }
+    
+    private final Semaphore semaStart ;
+    private final Semaphore semaFinish ;
+    private final AtomicReference<RuntimeException> thrownRuntimeException = new AtomicReference<>(null) ; 
+    private final AtomicReference<Error> thrownError = new AtomicReference<>(null) ;
+    private final Runnable action ;
+    
+    private ThreadTxn(Runnable action) {
+        this.action = action ;
+        this.semaStart = new Semaphore(0, true) ;
+        this.semaFinish = new Semaphore(0, true) ;
+    }
+    
+    /**
+     * Perform the Runnable, reporting any 
+     * {@link java.lang.RuntimeException} or {@link java.lang.Error}
+     */
+    public void run() { 
+        semaStart.release();
+        semaFinish.acquireUninterruptibly() ;
+        if ( thrownError.get() != null )
+            throw thrownError.get() ;
+        if ( thrownRuntimeException.get() != null )
+            throw thrownRuntimeException.get() ;
+    }
+    
+    // Called on the async thread.
+    private void trigger() {
+        try { action.run(); }
+        catch (Error error) { thrownError.set(error) ; throw error  ;}
+        catch (RuntimeException ex) { thrownRuntimeException.set(ex) ; throw ex ; }
+    }
+    
+    // System-shared executor.
+    private static Executor executor = Sys.executor ;
+    
+    /*package*/ static ThreadTxn create(Transactional trans, ReadWrite mode, Runnable action, boolean isCommit) {
+        Objects.requireNonNull(trans) ;
+        Objects.requireNonNull(mode) ;
+        Objects.requireNonNull(action) ;
+        
+        ThreadTxn threadAction = new ThreadTxn(action) ;
+        // Startup semaphore so that the thread has started by the
+        // time we exit this setup function. 
+        Semaphore semaStartup = new Semaphore(0, true) ;
+        executor.execute( ()-> {
+            // NB. trans.begin then semaStartup.release() ;
+            // This ensures that the transaction has really started.
+            trans.begin(mode) ;
+            
+            // Signal the creator (see below) that the transaction has started.
+            semaStartup.release() ;
+            
+            // Wait for the signal to run the action.
+            threadAction.semaStart.acquireUninterruptibly();
+            
+            try {
+                // Performane the action, catch and record any RuntimeException or Error. 
+                threadAction.trigger() ;
+                
+                // Finish transaction (if no throwable)
+                if ( mode == ReadWrite.WRITE ) {
+                    if ( isCommit )
+                        trans.commit();
+                    else
+                        trans.abort() ;
+                    trans.end() ;
+                } else {
+                    // Read
+                    if ( isCommit )
+                        trans.commit();
+                    trans.end() ;
+                }
+            } 
+            catch (Throwable ex) { 
+                       // Suppress now it has trigger transaction mechanism in
+                       // the presence of an unchecked exception.
+                       // Passed to the main thread via ThreadTxn
+            }
+            finally { threadAction.semaFinish.release() ; }
+        }) ;
+        // Don't return until the transaction has started.
+        semaStartup.acquireUninterruptibly();
+        return threadAction ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransInteger.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransInteger.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransInteger.java
new file mode 100644
index 0000000..5ef6791
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransInteger.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import java.io.IOException ;
+import java.nio.ByteBuffer ;
+import java.util.concurrent.atomic.AtomicLong ;
+
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.lib.FileOps ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.dboe.migrate.L;
+import org.apache.jena.dboe.transaction.txn.ComponentId;
+import org.apache.jena.dboe.transaction.txn.TransactionalComponentLifecycle;
+import org.apache.jena.dboe.transaction.txn.TxnId;
+import org.apache.jena.query.ReadWrite ;
+
+/** A transaction component with an integer supporting MR+SW (=one writer AND many readers).
+ * @see TransactionalInteger
+ */
+public class TransInteger extends TransactionalComponentLifecycle<TransInteger.IntegerState> {
+
+    private final AtomicLong value = new AtomicLong(-1712) ;
+    private final String filename ;
+    
+    /** Per transaction state - and per thread safe because we subclass 
+     * TransactionalComponentLifecycle
+     */ 
+    static class IntegerState {
+        long txnValue ;
+        public IntegerState(long v) { this.txnValue = v ; }
+    }
+    
+    static int counter = 0 ;
+    
+    /** In-memory, non persistent, transactional integer */
+    public TransInteger() { this(0L) ; }
+    
+    /** In-memory, non persistent, transactional integer */
+    public TransInteger(long v) {
+        this(null, ComponentId.allocLocal()) ;
+        value.set(v) ;
+    }
+
+    /** Persistent, transactional integer. The persistent state is held in
+     *  filename.  When first initialized, the value is 0L. 
+     * @param filename  Persistent state
+     * @param cid        Component id
+     */
+    public TransInteger(String filename, ComponentId cid) {
+        super(cid) ;
+        this.filename = filename ;
+        // Set the value now for "fast read" transactions.
+        readLocation() ;
+    }
+    
+    private void readLocation() {
+        if ( filename != null ) {
+            if ( ! FileOps.exists(filename) ) {
+                value.set(0L) ;
+                writeLocation() ;
+                return ;
+            }
+            long x = read(filename) ;
+            value.set(x);
+        }
+    }
+
+    private void writeLocation() {
+        writeLocation(value.get()) ;
+    }
+    
+    private void writeLocation(long value) {
+        if ( filename != null ) {
+            write(filename, value) ;
+        }
+    }
+
+    //-- Read/write the value
+    // This should really be checksum'ed or other internal check to make sure IO worked.  
+    private static long read(String filename) {
+        try {
+            String str = IO.readWholeFileAsUTF8(filename) ;
+            if ( str.endsWith("\n") ) {
+                str = str.substring(0, str.length()-1) ;
+            }
+            str = str.trim() ;
+            return Long.parseLong(str) ;
+        } 
+        catch (IOException ex) {
+            Log.error(TransInteger.class, "IOException: " + ex.getMessage(), ex) ;
+            IO.exception(ex) ;
+        }
+        catch (NumberFormatException ex) {
+            Log.error(TransInteger.class, "NumberformatException: " + ex.getMessage()) ;
+            throw new InternalErrorException(ex) ;
+        }
+        // Not reached.
+        return Long.MIN_VALUE ;
+    }
+
+    
+    private static void write(String filename, long value) {
+        try { L.writeStringAsUTF8(filename, Long.toString(value)) ; } 
+        catch (IOException ex) {}
+        catch (NumberFormatException ex) {}
+    }
+    
+    private boolean recoveryAction = false ; 
+    
+    @Override
+    public void startRecovery() {
+        recoveryAction = false ;
+    }
+
+    @Override
+    public void recover(ByteBuffer ref) {
+        long x = ref.getLong() ;
+        value.set(x) ;
+        recoveryAction = true ;
+    }
+    
+
+    @Override
+    public void finishRecovery() {
+        if ( recoveryAction )
+            writeLocation();
+        // Leave true as a record.
+    }
+
+    @Override
+    public void cleanStart() {
+        recoveryAction = false ;
+    }
+    
+    /** Set the value, return the old value*/ 
+    public void inc() {
+        checkWriteTxn() ;
+        IntegerState ts = getDataState() ;
+        ts.txnValue++ ;
+    }
+    
+    /** Set the value, return the old value*/ 
+    public long set(long x) {
+        checkWriteTxn() ;
+        IntegerState ts = getDataState() ;
+        long v = ts.txnValue ;
+        ts.txnValue = x ;
+        return v ;
+    }
+    
+
+    /** Return the current value in a transaction. s*/
+    public long read() {
+        checkTxn();
+        return getDataState().txnValue ;
+    }
+
+    /** Return the current value.
+     * If inside a transaction, return the transaction view of the value.
+     * If not in a transaction return the state value (effectively
+     * a read transaction, optimized by the fact that reading the
+     * {@code TransInteger} state is atomic).
+     */
+    public long get() {
+        if ( super.isActiveTxn() )
+            return getDataState().txnValue ;
+        else
+            return value.get() ;
+    }
+
+    /** Read the current global state (that is, the last committed value) outside a transaction. */
+    public long value() {
+        return value.get() ;
+    }
+
+    @Override
+    protected IntegerState _begin(ReadWrite readWrite, TxnId txnId) {
+        return createState();
+    }
+
+    private IntegerState createState() {
+        return new IntegerState(value.get()) ;
+    }
+    
+    @Override
+    protected IntegerState _promote(TxnId txnId, IntegerState state) {
+        return createState();
+    }
+
+    @Override
+    protected ByteBuffer _commitPrepare(TxnId txnId, IntegerState state) {
+        ByteBuffer x = ByteBuffer.allocate(Long.BYTES) ;
+        x.putLong(state.txnValue) ;
+        return x ;
+    }
+
+    @Override
+    protected void _commit(TxnId txnId, IntegerState state) {
+        writeLocation(state.txnValue) ;
+    }
+
+    @Override
+    protected void _commitEnd(TxnId txnId, IntegerState state) {
+        value.set(state.txnValue) ;
+    }
+    @Override
+    protected void _abort(TxnId txnId, IntegerState state) {
+        // Nothing
+    }
+
+    @Override
+    protected void _complete(TxnId txnId, IntegerState state) {
+        // Nothing
+    }
+
+    @Override 
+    protected void _shutdown() {
+    }
+    
+    @Override
+    public String toString() {
+        return String.valueOf(super.getComponentId()) ; 
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransLogger.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransLogger.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransLogger.java
new file mode 100644
index 0000000..fdeabd0
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransLogger.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import java.nio.ByteBuffer ;
+
+import org.apache.jena.atlas.logging.FmtLog ;
+import org.apache.jena.dboe.transaction.txn.ComponentId;
+import org.apache.jena.dboe.transaction.txn.SysTransState;
+import org.apache.jena.dboe.transaction.txn.Transaction;
+import org.apache.jena.dboe.transaction.txn.TransactionalComponent;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+/**
+ * Logging for transaction steps. This class is stateless in the transaction.
+ * When operations are called in the {@link TransactionalComponent} lifecycle,
+ * it logs the event.
+ */
+
+public class TransLogger implements TransactionalComponent {
+    private final Logger log ;
+    private final boolean everyEvent ; 
+    
+    /** Create a logger for begin-commit/abort-end */ 
+    public TransLogger() {
+        this(null, false) ;
+    }
+    
+    /** Create a logger, either just  begin-commit/abort-end or all steps */
+    public TransLogger(Logger logger) {
+        this(logger, false) ;
+    }
+
+    /** Create a logger, either just  begin-commit/abort-end or all steps */
+    public TransLogger(Logger logger, boolean all) {
+        if ( logger == null )
+            logger = LoggerFactory.getLogger(TransLogger.class) ;
+        this.log = logger ;
+        this.everyEvent = all ;
+    }
+
+    @Override
+    public ComponentId getComponentId() {
+//        if ( everyEvent )
+//            log.info("getComponentId") ; 
+        return null ;
+    }
+
+    @Override
+    public void startRecovery() {
+        if ( everyEvent )
+            log.info("startRecovery") ;
+    }
+
+    @Override
+    public void recover(ByteBuffer ref) {
+        // Is not called because this compoent vener writes a redo/undo action to the log.
+        if ( everyEvent )
+            log.info("recover") ;
+    }
+
+    @Override
+    public void finishRecovery() {
+        if ( everyEvent )
+            log.info("finishRecovery") ;
+    }
+
+    @Override
+    public void cleanStart() {
+        if ( everyEvent )
+            log.info("cleanStart") ;
+    }
+
+    @Override
+    public void begin(Transaction transaction) {
+        txnStep("begin", transaction) ;
+    }
+
+    @Override
+    public boolean promote(Transaction transaction) {
+        txnStep("promote", transaction) ;
+        return true ;
+    }
+
+    @Override
+    public ByteBuffer commitPrepare(Transaction transaction) {
+        if ( everyEvent )
+            txnStep("commitPrepare", transaction) ;
+        return null ;
+    }
+
+    @Override
+    public void commit(Transaction transaction) {
+        txnStep("commit", transaction) ;
+    }
+
+    @Override
+    public void commitEnd(Transaction transaction) {
+        if ( everyEvent )
+            txnStep("commitEnd", transaction) ;
+    }
+
+    @Override
+    public void abort(Transaction transaction) {
+        txnStep("abort", transaction) ;
+    }
+
+    @Override
+    public void complete(Transaction transaction) {
+        txnStep("complete", transaction) ;
+    }
+
+    @Override
+    public SysTransState detach() {
+        log.info("detach") ;
+        return null ;
+    }
+
+    @Override
+    public void attach(SysTransState systemState) {
+        log.info("attach") ;
+    }
+
+    @Override
+    public void shutdown() {
+        if ( everyEvent )
+            log.info("shutdown") ;
+    }
+    
+    private void txnStep(String opName, Transaction transaction) {
+        FmtLog.info(log, "%-8s %s", transaction.getTxnId(), opName) ;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransMonitor.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransMonitor.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransMonitor.java
new file mode 100644
index 0000000..d630b83
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransMonitor.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import java.io.PrintStream ;
+import java.nio.ByteBuffer ;
+import java.util.LinkedHashMap ;
+import java.util.Map ;
+import java.util.concurrent.atomic.LongAdder ;
+import java.util.stream.Collectors ;
+
+import org.apache.jena.dboe.transaction.txn.ComponentId;
+import org.apache.jena.dboe.transaction.txn.SysTransState;
+import org.apache.jena.dboe.transaction.txn.Transaction;
+import org.apache.jena.dboe.transaction.txn.TransactionalComponent;
+
+/** This class is stateless in the transaction but it records counts of
+ * every {@link TransactionalComponent} operations.
+ * For each operation called "ABC" there is a member field "counterABC".  
+ */
+public class TransMonitor implements TransactionalComponent {
+    
+    // LongAdder for stats (better from mostly write, not consistent read)
+    
+    /** Counters, in initialization order */
+    private Map<String, LongAdder> counters = new LinkedHashMap<>() ;
+    private final ComponentId componentId ;
+    
+    private LongAdder allocCounter(String string) {
+        LongAdder counter = new LongAdder() ;
+        counters.put(string, counter) ;
+        return counter ;
+    }
+    public TransMonitor(ComponentId cid) { 
+        this.componentId = cid ;
+    }
+    
+    /** Reset all counters to zero */
+    public void reset() {
+        counters.forEach( (s,c) -> c.reset()) ; 
+    }
+
+    /** Get a copy of the counters with current values.
+     * The values are as of the point of this being called and are not changed
+     * by any later calls to monitored operations.  
+     */
+    public Map<String, Long> getAll() {
+        return counters.entrySet().stream()
+            .collect(Collectors.toMap(
+                                      e -> e.getKey(),
+                                      e -> e.getValue().sum()
+                ));
+    }
+    
+    /** Print the counters state. */
+    public void print() {
+        print(System.out) ;
+    }
+
+    /** Print the counters state. */
+    public void print(PrintStream ps) {
+        ps.println("Transaction Counters:") ;
+        counters.forEach( (s,c) -> {
+            ps.printf("   %-15s %4d\n", s, c.longValue()) ;
+        }) ;
+    }
+
+    public LongAdder counterGetComponentId = allocCounter("getComponentId") ;
+
+    @Override
+    public ComponentId getComponentId() {
+        counterGetComponentId.increment() ;
+        return componentId ;
+    }
+
+    public LongAdder counterStartRecovery = allocCounter("startRecovery") ;
+
+    @Override
+    public void startRecovery() {
+        counterStartRecovery.increment() ;
+    }
+
+    public LongAdder counterRecover = allocCounter("recover") ;
+
+    @Override
+    public void recover(ByteBuffer ref) {
+        counterRecover.increment() ;
+    }
+
+    public LongAdder counterFinishRecovery = allocCounter("finishRecovery") ;
+
+    @Override
+    public void finishRecovery() {
+        counterFinishRecovery.increment() ;
+    }
+    
+    public LongAdder counterCleanStart = allocCounter("finishRecovery") ;
+    
+    @Override
+    public void cleanStart() {
+        counterCleanStart.increment() ;
+    }
+    
+    public LongAdder counterBegin = allocCounter("begin") ;
+
+    @Override
+    public void begin(Transaction transaction) {
+        counterBegin.increment() ;
+    }
+    
+    public LongAdder counterPromote = allocCounter("promote") ;
+    
+    @Override
+    public boolean promote(Transaction transaction) {
+        counterPromote.increment() ;
+        return true ;
+    }
+
+    public LongAdder counterCommitPrepare = allocCounter("commitPrepare") ;
+
+    @Override
+    public ByteBuffer commitPrepare(Transaction transaction) {
+        counterCommitPrepare.increment() ;
+        return null ;
+    }
+
+    public LongAdder counterCommit = allocCounter("commit") ;
+
+    @Override
+    public void commit(Transaction transaction) {
+        counterCommit.increment() ;
+    }
+
+    public LongAdder counterCommitEnd = allocCounter("commitEnd") ;
+
+    @Override
+    public void commitEnd(Transaction transaction) {
+        counterCommitEnd.increment() ;
+    }
+
+    public LongAdder counterAbort = allocCounter("abort") ;
+
+    @Override
+    public void abort(Transaction transaction) {
+        counterAbort.increment() ;
+    }
+
+    public LongAdder counterComplete = allocCounter("complete") ;
+
+    @Override
+    public void complete(Transaction transaction) {
+        counterComplete.increment() ;
+    }
+
+    public LongAdder counterDetach = allocCounter("detach") ;
+    
+    @Override
+    public SysTransState detach() {
+        counterDetach.increment() ;
+        return null ;
+    }
+
+    public LongAdder counterAttach = allocCounter("attach") ;
+
+    @Override
+    public void attach(SysTransState systemState) {
+        counterAttach.increment() ;
+    }
+    
+    public LongAdder counterShutdown = allocCounter("shutdown") ;
+
+    @Override
+    public void shutdown() {
+        counterShutdown.increment() ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/Transactional.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/Transactional.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/Transactional.java
new file mode 100644
index 0000000..176c3d0
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/Transactional.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import org.apache.jena.dboe.jenax.Txn;
+import org.apache.jena.query.ReadWrite ;
+
+/** Interface that encapsulates the  begin/abort|commit/end operations.
+ * <p>The read lifecycle is:
+ * <pre> begin(READ) ... end()</pre>
+ * <p>{@code commit} and {@code abort} are allowed. 
+ * <p>The write lifecycle is:
+ * <pre> begin(WRITE) ... abort() or commit()</pre>
+ * <p>{@code end()} is optional but preferred.
+ * <p>
+ * Helper code is available {@link Txn} so, for example:
+ * <pre>Txn.execRead(dataset, ()-> { ... sparql query ... });</pre> 
+ * <pre>Txn.execWrite(dataset, ()-> { ... sparql update ... });</pre>
+ * <p>
+ * Directly called, code might look like:
+ * <pre>
+ *     Transactional object = ...
+ *     object.begin(ReadWrite.READ) ;
+ *     try {
+ *       ... actions inside a read transaction ...
+ *     } finally { object.end() ; }
+ * </pre>
+ * or
+ * <pre>
+ *     Transactional object = ...
+ *     object.begin(ReadWrite.WRITE) ;
+ *     try {
+ *        ... actions inside a write transaction ...
+ *        object.commit() ;
+ *     } finally {
+ *        // This causes an abort if {@code commit} has not been called.
+ *        object.end() ;
+ *     }
+ * </pre>
+ * Exceptions will not be thrown.
+ * If any do occur, this indicates serious internal problems with the transaction system.
+ */
+public interface Transactional extends org.apache.jena.sparql.core.Transactional
+{
+   /** Start either a READ or WRITE transaction */
+   @Override
+   public void begin(ReadWrite readWrite) ;
+   
+   /** Attempt to promote a read transaction to a write transaction.
+    * This is not guaranteed to succeed - any changes by another write transaction
+    * may restrict promotion.  
+    * <p>
+    * In the MR+SW implementation, any intervening write transaction will block promotion.
+    * <p>
+    * Promoting a transaction which is already a write transaction will return true. 
+    * <p>
+    * Consider also:
+    *  <pre>
+    *    .end() ;
+    *    .begin(WRITE) ;
+    *  </pre>
+    *  to see any intermediate commits from another writer.
+    * 
+    * @return boolean indicating whether the transaction is now a write transaction or not.
+    */
+   public boolean promote() ;
+
+   /** Commit a transaction - finish the transaction and make any changes permanent (if a "write" transaction) */
+   @Override
+   public void commit() ;
+   
+   /** Abort a transaction - finish the transaction and undo any changes (if a "write" transaction) */  
+   @Override
+   public void abort() ;
+   
+   /** Finish the transaction - if a write transaction and commit() has not been called, then abort. */
+   @Override
+   public void end() ;
+   
+   /** Say whether inside a transaction. */ 
+   @Override
+   public boolean isInTransaction() ;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalFactory.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalFactory.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalFactory.java
new file mode 100644
index 0000000..c042e27
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import org.apache.jena.dboe.base.file.Location;
+import org.apache.jena.dboe.transaction.txn.TransactionCoordinator;
+import org.apache.jena.dboe.transaction.txn.TransactionalBase;
+import org.apache.jena.dboe.transaction.txn.TransactionalComponent;
+import org.apache.jena.dboe.transaction.txn.TransactionalSystem;
+import org.apache.jena.dboe.transaction.txn.journal.Journal;
+
+/** Helper operations for creating a {@link Transactional}.
+ * The operations capture some common patterns.
+ */
+public class TransactionalFactory {
+
+    /** Create, and start, management of a number of {@link TransactionalComponent}s */ 
+    public static Transactional createTransactional(Location location, TransactionalComponent ... elements) {
+        TransactionCoordinator coord = new TransactionCoordinator(location) ;
+        return createTransactional(coord, elements) ;
+    }
+
+    /** Create, and start, management of a number of {@link TransactionalComponent}s */ 
+    public static Transactional createTransactional(Journal journal, TransactionalComponent ... elements) {
+        TransactionCoordinator coord = new TransactionCoordinator(journal) ;
+        return createTransactional(coord, elements) ;
+    }
+
+    private static Transactional createTransactional(TransactionCoordinator coord, TransactionalComponent[] elements) {
+        for ( TransactionalComponent tc : elements ) {
+            coord.add(tc) ;
+        }
+        TransactionalBase base = new TransactionalBase(coord) ;
+        coord.start() ;
+        return base ;
+    }
+    
+    /** Create, but do not start, a {@link TransactionalSystem} from a {@link TransactionCoordinator} */
+    public static TransactionalSystem createTransactionalSystem(TransactionCoordinator coord) {
+        return new TransactionalBase(coord) ;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalMonitor.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalMonitor.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalMonitor.java
new file mode 100644
index 0000000..df7b233
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/TransactionalMonitor.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction;
+
+import org.apache.jena.query.ReadWrite ;
+
+/** Interface for the Transactional interface */
+public interface TransactionalMonitor {
+    default void startBegin(ReadWrite mode)     {}
+    default void finishBegin(ReadWrite mode)    {}
+
+    default void startPromote()     {}
+    default void finishPromote()    {}
+
+    default void startCommit()      {}
+    default void finishCommit()     {}
+
+    default void startAbort()       {}
+    default void finishAbort()      {}
+
+    default void startEnd()         {}
+    default void finishEnd()        {}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentGroup.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentGroup.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentGroup.java
new file mode 100644
index 0000000..e2d4d3b
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentGroup.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction.txn;
+
+import java.util.Arrays ;
+import java.util.HashMap ;
+import java.util.Map ;
+import java.util.Objects ;
+import java.util.function.BiConsumer ;
+import java.util.function.Consumer ;
+
+import org.apache.jena.atlas.logging.Log ;
+
+final
+public class ComponentGroup {
+    private Map<ComponentId, TransactionalComponent> group = new HashMap<>() ;
+    
+    public ComponentGroup(TransactionalComponent...components) {
+        Arrays.asList(components).forEach(this::add);
+    }
+
+    private ComponentGroup(Map<ComponentId, TransactionalComponent> group) {
+        this.group.putAll(group); 
+    }
+    
+    public void add(TransactionalComponent component) {
+        Objects.requireNonNull(component) ;
+        //Log.info(this, "add("+component.getComponentId()+")") ;
+        if ( component.getComponentId() == null )
+            Log.warn(this,  "Null component id - likely to be overwritten: "+component) ;
+            
+        if ( group.containsKey(component.getComponentId()) ) {
+            Log.warn(this,  component.getComponentId().toString()) ;
+            Log.warn(this,  "Add component already in the group: "+component) ;
+        }
+        
+        group.put(component.getComponentId(), component) ;
+    }
+    
+    /*package*/ void remove(ComponentId componentId) {
+        group.remove(componentId) ;
+    }
+
+    public TransactionalComponent findComponent(ComponentId componentId) {
+        return group.get(componentId) ;
+    }
+    
+    public void forEachComponent(Consumer<? super TransactionalComponent> action) {
+        group.values().forEach(action) ;
+    }
+    
+    public void forEach(BiConsumer<ComponentId, TransactionalComponent> action) {
+        group.forEach(action);
+    }
+
+    public void addAll(ComponentGroup components) {
+        this.group.putAll(components.group); 
+    }
+    
+    public int size() { return group.size() ; }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentId.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentId.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentId.java
new file mode 100644
index 0000000..5ea4995
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentId.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction.txn;
+
+import java.util.Arrays ;
+import java.util.UUID ;
+
+import org.apache.jena.atlas.lib.Bytes ;
+
+/** A {@code ComponentId} consists of two parts: a globally unique context 
+ * (roughly - the domain where the {@code ComponentId} is valid)
+ * and an id within the context.
+ * Context is often a single coordinator but can be, for example,
+ * a distributed transaction coordinator.    
+ */
+
+public class ComponentId {
+    // Fixed size. 
+    public static final int SIZE = 4 ;
+    private final UUID coordinatorId ;
+    private final byte[] bytes ;
+    // Just a helper for development.  Not persisted in the journal.
+    private final String displayName ;
+    
+    /** Create a new ComponentId from the given bytes.
+     * The bytes are <em>not</em> copied. 
+     * The caller must not modify them after this call.
+     * The static method {@link #create(String, byte[])}
+     * does the copy.
+     */
+    private ComponentId(String label, UUID coordinatorId, byte[] bytes) {
+        this.coordinatorId = coordinatorId ;
+        if ( label == null )
+            label = "" ;
+        if ( bytes.length > SIZE )
+            throw new IllegalArgumentException("Bytes for ComponentId too long "+bytes.length+" > "+SIZE) ;
+        if ( bytes.length < SIZE )
+            // Make safe.
+            bytes = Arrays.copyOf(bytes, SIZE) ;
+        this.bytes = bytes ;
+        this.displayName = label ;
+    }
+    
+    public byte[] getBytes() { return bytes ; }
+    
+    public UUID getBaseId() { return coordinatorId ; }
+    
+    public String label() { return displayName ; }
+    
+    @Override
+    public String toString() { return displayName+"["+Bytes.asHex(bytes)+"]" ; }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31 ;
+        int result = 1 ;
+        result = prime * result + Arrays.hashCode(bytes) ;
+        return result ;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj )
+            return true ;
+        if ( obj == null )
+            return false ;
+        if ( getClass() != obj.getClass() )
+            return false ;
+        ComponentId other = (ComponentId)obj ;
+        if ( !Arrays.equals(bytes, other.bytes) )
+            return false ;
+        return true ;
+    }
+
+    /** Create a ComponentId from the given bytes */
+    public static ComponentId create(UUID coordinatorBase, byte[] bytes) {
+        bytes = Arrays.copyOf(bytes, bytes.length) ;
+        return new ComponentId(null, coordinatorBase, bytes) ;
+    }
+    
+    /** Given a base componentId, create a derived (different) one.
+     * This is deterministically done based on  baseComponentId and index.
+     * The label is just for display purposes.
+     */ 
+    public static ComponentId alloc(String label, UUID coordinatorBase, int index) {
+        byte[] bytes = Bytes.intToBytes(index) ;
+        return new ComponentId(label, coordinatorBase, bytes) ;
+    }
+    
+//    private static ComponentId create(byte[] bytes, String label, int index) {
+//        bytes = Arrays.copyOf(bytes, bytes.length) ;
+//        int x = Bytes.getInt(bytes, bytes.length-SystemBase.SizeOfInt) ;
+//        x = x ^ index ;
+//        Bytes.setInt(x, bytes, bytes.length - SystemBase.SizeOfInt) ;
+//        ComponentId cid = new ComponentId(label+"-"+index, bytes) ;
+//        return cid ;
+//    }
+    
+    static int counter = 0 ;
+    /** Return a fresh ComponentId (not preserved across JVM runs) */ 
+    public static ComponentId allocLocal() {
+        counter++ ;
+        UUID uuid = UUID.randomUUID() ;
+        return alloc("Local-"+counter, uuid, counter) ;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentIds.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentIds.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentIds.java
new file mode 100644
index 0000000..3002e47
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/ComponentIds.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction.txn;
+
+
+/** Some fixed, marker, {@link ComponentId}s */
+public class ComponentIds {
+    
+    public static final ComponentId idNull          = make("Monitor",  -9999) ;
+    public static final ComponentId idSystem        = make("System",   -9988) ;
+    
+    private static ComponentId make(String string, int v) {
+        return ComponentId.alloc(string, null, v) ;
+    }
+    
+    
+//    
+//    // Linux : "uuid -v 4"
+//    
+//    /* For single instance components and base ids for incremental registration */
+//    public static final ComponentId idTxnMRSW       = make("MRSW",     "93a58341-ed53-4f0c-bac1-d9969ea38cf3") ;
+//    // TODO tie to registration (this predates)
+//    public static final ComponentId idTxnCounter    = make("Counter",  "6b901671-e6db-45c5-9217-7506d21a0000") ;
+//    public static final ComponentId idMonitor       = make("Monitor",  "c4d8a1e6-052b-413a-8d80-c5a6b442e608") ;
+//    public static final ComponentId idNull          = make("Monitor",  "e6e31271-b6dc-452c-b624-d4e099464365") ;
+//    public static final ComponentId idSystem        = make("System",   "95e0f729-ad29-48b2-bd70-e3738663c578") ;
+//    public static final ComponentId idBlobBase      = make("Blob",     "43436b91-87ce-4d6b-827c-c3b9ea6536ba") ;
+//    public static final ComponentId idDev           = make("Blob",     "82a6833a-1475-495a-83ca-10370c7c40cd") ;
+//    
+//    public static ComponentId make(String label, String uuidStr) {
+//        byte[] bytes = L.uuidAsBytes(uuidStr) ;
+//        return ComponentId.create(label, bytes) ;
+//    }
+    
+    /* For later
+    82a6833a-1475-495a-83ca-10370c7c40cd
+    1d32231b-aa11-47ed-8893-6b36673fe04c
+    27c4845e-c05a-410d-8c74-278a23b03bbd
+    f841ba46-a297-487d-b622-dd452c888dab
+    09efba54-7428-4689-929d-b1719a56c345
+    a9fbdc3c-442d-4086-8f40-b6ef773871b9
+    */
+
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/PrepareState.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/PrepareState.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/PrepareState.java
new file mode 100644
index 0000000..3323c45
--- /dev/null
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/PrepareState.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.dboe.transaction.txn;
+
+import java.nio.ByteBuffer ;
+
+final
+public class PrepareState {
+    private final ComponentId component ;
+    private final ByteBuffer data ;
+    
+    public /*For testing*/ PrepareState(ComponentId compoent, ByteBuffer data) {
+        this.component = compoent ;
+        this.data = data ;
+    }
+
+    public ComponentId getComponent() {
+        return component ;
+    }
+
+    public ByteBuffer getData() {
+        return data ;
+    }
+}
+