diff --git a/Database/APR/RootStorageSvc/share/branchContIdx_test.ref b/Database/APR/RootStorageSvc/share/branchContIdx_test.ref
index b136da4a515940bba6fe6096163822f6a33e8b05..2478df0436b7f274fc0f85a76fc3c53524374556 100644
--- a/Database/APR/RootStorageSvc/share/branchContIdx_test.ref
+++ b/Database/APR/RootStorageSvc/share/branchContIdx_test.ref
@@ -2,19 +2,28 @@ Starting branchContIdx_test
 Start WRITE session
 Session connect
 Sample Tokens to written objects:
-Token for object A1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000000]
-Token for object A2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000001]
-Token for object A3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000002]
-Token for object A4 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000003]
-Token for object A5 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000004]
-Token for object A6 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000005]
-Token for object B1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000004-000072F700000000]
-Token for object B2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000004-000072F700000001]
+Token for object A1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000000]
+Token for object A2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000001]
+Token for object A3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000002]
+Token for object A4 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000003]
+Token for object A5 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000004]
+Token for object A6 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000005]
+Token for object B1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000000]
+Token for object B2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000001]
+Token for object B3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000002]
+Token for object C1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000000]
+Token for object C2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000003]
+Token for object C3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000006]
 
 Starting READ
 read back A1: This is my string A1
+read back A7: This is my string A7
+read back C3: This is my string C3
 read back B1: This is my string B1
+read back C2: This is my string C2
 read back A3: This is my string A3
+read back C1: This is my string C1
+read back B3: This is my string B3
 read back A6: This is my string A6
 read back A4: This is my string A4
 read back B2: This is my string B2
diff --git a/Database/APR/RootStorageSvc/src/RootDatabase.cpp b/Database/APR/RootStorageSvc/src/RootDatabase.cpp
index 3740ebadd3652590dfb79eaba6e583d37913bd94..03e2fad9fe82e4f0d9e6eaf60c8b9d5d20449077 100644
--- a/Database/APR/RootStorageSvc/src/RootDatabase.cpp
+++ b/Database/APR/RootStorageSvc/src/RootDatabase.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -21,7 +21,6 @@
 #include "GaudiKernel/ISvcLocator.h"
 #include "GaudiKernel/IFileMgr.h"
 
-#include <iostream>
 #include <string>
 #include <cerrno>
 
@@ -49,6 +48,7 @@ RootDatabase::RootDatabase() :
         m_defWritePolicy(TObject::kOverwrite),   // On write create new versions
         m_branchOffsetTabLen(0),
         m_defTreeCacheLearnEvents(-1),
+        m_indexMasterID(0),
         m_fileMgr(nullptr)
 {
   m_counters[READ_COUNTER] = m_counters[WRITE_COUNTER] = m_counters[OTHER_COUNTER] = 0;
@@ -73,6 +73,7 @@ long long int RootDatabase::size()  const   {
 
 /// Callback after successful open of a database object
 DbStatus RootDatabase::onOpen(DbDatabase& dbH, DbAccessMode mode)  {
+  m_dbH = dbH;
   std::string par_val;
   DbPrint log("RootDatabase.onOpen");
   if ( !dbH.param("FORMAT_VSN", par_val).isSuccess() )  {
@@ -98,7 +99,8 @@ DbStatus RootDatabase::onOpen(DbDatabase& dbH, DbAccessMode mode)  {
 }
 
 // Open a new root Database: Access the TFile
-DbStatus RootDatabase::open(const DbDomain& domH,const std::string& nam,DbAccessMode mode)   {
+DbStatus RootDatabase::open(const DbDomain& domH,const std::string& nam,DbAccessMode mode)
+{
   DbPrint log("RootDatabase.open");
   const char* fname = nam.c_str();
   Bool_t result = ( mode == pool::READ ) ? kFALSE : gSystem->AccessPathName(fname, kFileExists);
@@ -590,6 +592,19 @@ DbStatus RootDatabase::setOption(const DbOption& opt)  {
         return Success;
       }
       break;
+    case 'I':
+       if( !strcasecmp(n, "INDEX_MASTER") ) {
+          DbPrint log("RootDatabase::setOption");
+          char *s = nullptr;
+          if( opt._getValue(s).isSuccess() and s ) {
+             m_indexMaster = s;
+             log << DbPrintLvl::Debug << "INDEX_MASTER set to " << m_indexMaster << DbPrint::endmsg;
+             return Success;
+          }
+          log << DbPrintLvl::Debug << "INDEX_MASTER: s=" << (void*)s << DbPrint::endmsg;
+          return Error;
+       }
+      break;
     case 'M':
       if ( !strcasecmp(n, "MAXIMUM_BUFFERSIZE") )         // int
         return opt._getValue(m_maxBufferSize);
@@ -622,7 +637,7 @@ DbStatus RootDatabase::setOption(const DbOption& opt)  {
       break;
     case 'T':
        if ( !strcasecmp(n+5,"BRANCH_OFFSETTAB_LEN") )  {
-	  return opt._getValue(m_branchOffsetTabLen);
+          return opt._getValue(m_branchOffsetTabLen);
        }
        else if ( !strcasecmp(n+5,"MAX_SIZE") )  {
 	  long long int max_size = TTree::GetMaxTreeSize();
@@ -904,7 +919,40 @@ DbStatus RootDatabase::transAct(Transaction::Action action)
          }
       }
    }
+
+   if( !m_indexMaster.empty() ) {
+      DbPrint log( m_file->GetName() );
+      log << DbPrintLvl::Debug << "Synchronizing indexes to master: " <<  m_indexMaster << DbPrint::endmsg;
+      std::vector<IDbContainer*> containers;
+      m_dbH.containers(containers);
+      m_indexMasterID = 0;
+      if( m_indexMaster == "*" ) {
+         // find the biggest index ID
+         for( auto c : containers ) {
+            long long nextID = c->nextRecordId() & 0xFFFFFFFF;
+            if( nextID > m_indexMasterID ) m_indexMasterID = nextID;
+         }
+      } else {
+         // look for the master by name
+         for( auto c = containers.begin(); c !=  containers.end(); ++c ) {
+            if( (*c)->name() == m_indexMaster ) {
+               m_indexMasterID = (*c)->nextRecordId() & 0xFFFFFFFF;
+               // cout << "Found master index: " << (*c)->name() << "  next ID= " << m_indexMasterID  << endl;
+               containers.erase(c);
+               break;
+            }
+         }
+      }
+      // synchronize all container indices
+      if( m_indexMasterID > 0 ) {
+         // go back by one, so nextID in other indices is equal the last ID in master
+         // this works if synchronizing in separate commits - but not in the same commit!
+         --m_indexMasterID;
+         for( auto c: containers ) {
+            c->useNextRecordId( m_indexMasterID );
+         }
+      }
+   }
+   
    return Success;
 }
-
-     
diff --git a/Database/APR/RootStorageSvc/src/RootDatabase.h b/Database/APR/RootStorageSvc/src/RootDatabase.h
index e2898c1e75d30139a4b03e6e181d2b8db033d4b2..b27039549055e45d85c469cbd91465b93f9868c1 100644
--- a/Database/APR/RootStorageSvc/src/RootDatabase.h
+++ b/Database/APR/RootStorageSvc/src/RootDatabase.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -13,6 +13,7 @@
 
 // Framework include files
 #include "StorageSvc/IDbDatabase.h"
+#include "StorageSvc/DbDatabase.h"
 
 #include <set>
 #include <map>
@@ -44,6 +45,8 @@ namespace pool  {
   public:
     enum { READ_COUNTER = 0, WRITE_COUNTER = 1, OTHER_COUNTER = 2 };
   private:
+    /// Parent Database handle
+    DbDatabase    m_dbH;
     /// Reference to the actual implemented file 
     TFile*        m_file;
     /// Persistency format version
@@ -73,6 +76,11 @@ namespace pool  {
     /// Default tree cache learn events
     int           m_defTreeCacheLearnEvents;
 
+    /// name of the container with master index ('*' means use the biggest)
+    std::string   m_indexMaster;
+    /// nextID of the master index
+    long long     m_indexMasterID;
+
     /* ---  variables used with TREE_AUTO_FLUSH option for
             managing combined TTree::Fill for branch containers
     */
@@ -84,12 +92,12 @@ namespace pool  {
     std::map< TTree*, ContainerSet_t >  m_containersInTree;
     
     std::map< std::string, int >        m_customSplitLevel;
-    
-    IFileMgr*   m_fileMgr;
+
+    IFileMgr*     m_fileMgr;
 
     // mutex to prevent concurrent read I/O from AuxDynReader
     std::recursive_mutex  m_iomutex;
-    
+
   public:
     /// Standard Constuctor
     RootDatabase();
@@ -124,6 +132,8 @@ namespace pool  {
     
     void        registerBranchContainer(RootTreeContainer*);
 
+    long long   currentIndexMasterID() const   { return m_indexMasterID; }
+
     /// provide access to the I/O mutex for AuxDynReader and Containers
     std::recursive_mutex& ioMutex()         { return m_iomutex; }
     
diff --git a/Database/APR/RootStorageSvc/src/RootTreeContainer.h b/Database/APR/RootStorageSvc/src/RootTreeContainer.h
index 1dd8e1ba336f1085e64cb6b097701e0877139d42..f5e5f3749ead11faa6d1805fc14163706f0322fe 100755
--- a/Database/APR/RootStorageSvc/src/RootTreeContainer.h
+++ b/Database/APR/RootStorageSvc/src/RootTreeContainer.h
@@ -138,7 +138,7 @@ namespace pool  {
     /// Parent Database handle
     DbDatabase         m_dbH;
     /// Root database file reference
-    RootDatabase*         m_rootDb;
+    RootDatabase*      m_rootDb;
     /// Branch name, if branch is specified by user.
     std::string        m_branchName;
     /// Number of bytes written/read during last operation. Set to -1 if it failed.
@@ -199,7 +199,7 @@ namespace pool  {
     virtual DbStatus open(DbDatabase& dbH, 
                           const std::string& nam, 
                           const DbTypeInfo* info,
-                          DbAccessMode mod);
+                          DbAccessMode mod) override;
 
     /// Access options
     /** @param opt      [IN]  Reference to option object.
diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp
index e12a05d863d8f0e0fc38e92028bf8829386b2d66..5e2ade1b7bb6429b9202063fb3f157ba7b995d42 100644
--- a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp
+++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp
@@ -1,8 +1,10 @@
 /*
- *   Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+ *   Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
  *   */
 
 // Local implementation files
+#include "StorageSvc/DbOption.h"
+#include "RootDatabase.h"
 #include "RootTreeIndexContainer.h"
 
 // Root include files
@@ -13,14 +15,35 @@ using namespace pool;
 using namespace std;
 
 RootTreeIndexContainer::RootTreeIndexContainer() :
-   m_indexBranch(nullptr), m_index_entries(0), m_index_multi( getpid() )
+   m_indexBranch(nullptr), m_index_entries(0), m_index_multi( getpid() ), m_indexBump(0)
 { }
 
 
+DbStatus RootTreeIndexContainer::open( DbDatabase& dbH, 
+                                       const std::string& nam,
+                                       const DbTypeInfo* info,
+                                       DbAccessMode mod)
+{
+   auto db = static_cast<const RootDatabase*>( dbH.info() );
+   m_indexBump = db? db->currentIndexMasterID() : 0;
+   return RootTreeContainer::open( dbH, nam, info, mod );
+}
+
+
 long long int RootTreeIndexContainer::nextRecordId()
 {
    long long id = m_index_multi;
-   return (id << 32) + RootTreeContainer::nextRecordId();
+   return (id << 32) + RootTreeContainer::nextRecordId() + m_indexBump;
+}
+
+void RootTreeIndexContainer::useNextRecordId(long long int nextID)
+{
+   // Find out how this TTree index is behind the master index in the DB
+   m_indexBump = m_indexBranch? nextID - m_indexBranch->GetEntries() : nextID;
+   if( m_indexBump < 0 ) {
+      // Seems this index is ahead of the master, cannot sync
+      m_indexBump = 0;
+   }
 }
 
 
diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h
index cfb09f21231186d206d321c896aec4d595faa309..b1f9984ecf070599026bc0678a8063fb72d383d0 100644
--- a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h
+++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+ *   Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
  *   */
 
 #ifndef POOL_ROOTTREEINDEXCONTAINER_H
@@ -39,8 +39,14 @@ namespace pool {
       /// Standard destructor
       virtual ~RootTreeIndexContainer() {}
 
+      /// Open the container
+      virtual DbStatus open(DbDatabase&, const std::string&, const DbTypeInfo*, DbAccessMode) override final;
+
       /// Number of entries within the container
-      virtual long long int nextRecordId();
+      virtual long long int nextRecordId() override final;
+
+      /// Suggest next Record ID for tbe next object written - for synced indexes
+      virtual void useNextRecordId(long long int) override final;
 
       /// Find object by object identifier and load it into memory
       /** @param  ptr    [IN/OUT]  ROOT-style address of the pointer to object
@@ -63,6 +69,11 @@ namespace pool {
       const int m_index_multi;
       /// Index (64 bit)
       long long int m_index;
+
+      /// How much to increase nextRecordID to keep index values synced with other containers
+      long long int m_indexBump;
    };
 }
 #endif //POOL_ROOTTREEINDEXCONTAINER_H
+
+
diff --git a/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx b/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx
index 2aaf732870c246ef9b23132dc5cab78142532a83..fc101270125c084f59f6926a7af6cbe22c4dd687 100644
--- a/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx
+++ b/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 /**
@@ -25,7 +25,9 @@
 #include "StorageSvc/FileDescriptor.h"
 #include "StorageSvc/DbReflex.h"
 #include "StorageSvc/DbString.h"
+#include "StorageSvc/DbOption.h"
 
+using namespace pool;
 using namespace std;
 
 const string            filename = "branchContIdx_testfile.root";    // test file name
@@ -35,8 +37,9 @@ const string            filename = "branchContIdx_testfile.root";    // test fil
 //const string            containerNameB = "ContainerB";               // container for objects B
 
 // use branch containes
-const string            containerNameA = "Containers(A)";               // container for objects A
-const string            containerNameB = "Containers(B)";               // container for objects B
+const string            containerNameA = "Containers(A)";            // branch container for objects A
+const string            containerNameB = "Containers(B)";            // branch container for objects B
+const string            containerNameC = "ContainerC";               // tree container for objects C
 
 
 //const pool::DbType      storageType = pool::ROOTTREE_StorageType;
@@ -48,12 +51,19 @@ pool::DbString       myStringA3("This is my string A3");
 pool::DbString       myStringA4("This is my string A4");
 pool::DbString       myStringA5("This is my string A5");
 pool::DbString       myStringA6("This is my string A6");
+pool::DbString       myStringA7("This is my string A7");
 
 pool::DbString       myStringB1("This is my string B1");
 pool::DbString       myStringB2("This is my string B2");
+pool::DbString       myStringB3("This is my string B3");
+
+pool::DbString       myStringC1("This is my string C1");
+pool::DbString       myStringC2("This is my string C2");
+pool::DbString       myStringC3("This is my string C3");
 
 // string tokens to written objects, for use when reading back
-string refA1, refA2, refA3, refA4, refA5, refA6, refB1, refB2;
+string refA1, refA2, refA3, refA4, refA5, refA6, refA7;
+string refB1, refB2, refB3, refC1, refC2, refC3;
 
 
 int main() {
@@ -93,6 +103,18 @@ int main() {
       throw std::runtime_error( "Could not create a persistent shape." );
    }
 
+   // Get IStorageExplorer IFace to set options
+   void *p = nullptr;
+   storSvc->queryInterface( IStorageExplorer::interfaceID(), &p );
+   IStorageExplorer *storage = (IStorageExplorer*)p;
+   if( !storage ) {
+      throw std::runtime_error( "Failed to retrieve IStorageExplorer" );
+   }
+   // Set container for master index (enables index synchronization between TTrees)
+   //DbOption masterIdxOpt("INDEX_MASTER", "", containerNameA.c_str());
+   DbOption masterIdxOpt("INDEX_MASTER", "", "*");
+   storage->setDatabaseOption(fd, masterIdxOpt);
+
    // Commit here to test empty commits
    if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) {
       throw std::runtime_error( "Empty commit FAILED" );
@@ -106,26 +128,34 @@ int main() {
       }
       return token;
    };
+
+   auto Commit = [&](const int) {
+      if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) {
+         throw std::runtime_error( "Commit FAILED" );
+      }
+   };
    
    refA1 = writeStr(containerNameA, myStringA1)->toString();
    refA2 = writeStr(containerNameA, myStringA2)->toString();
    refA3 = writeStr(containerNameA, myStringA3)->toString();
    refB1 = writeStr(containerNameB, myStringB1)->toString();
+   refC1 = writeStr(containerNameC, myStringC1)->toString();
 
-   // Commit
-   if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) {
-      throw std::runtime_error( "Commit FAILED" );
-   }
+   Commit(1);
 
    refA4 = writeStr(containerNameA, myStringA4)->toString();
    refB2 = writeStr(containerNameB, myStringB2)->toString();
+   refC2 = writeStr(containerNameC, myStringC2)->toString();
    refA5 = writeStr(containerNameA, myStringA5)->toString();
    refA6 = writeStr(containerNameA, myStringA6)->toString();
 
-   // Commit again
-   if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) {
-      throw std::runtime_error( "Commit FAILED" );
-   }
+   Commit(2);
+
+   refA7 = writeStr(containerNameA, myStringA7)->toString();
+   refC3 = writeStr(containerNameC, myStringC3)->toString();
+   refB3 = writeStr(containerNameB, myStringB3)->toString();
+
+   Commit(3);
 
    // Close session
    if( !storSvc->disconnect( fd ).isSuccess() ) {
@@ -147,6 +177,10 @@ int main() {
    cout << "Token for object A6 = " << refA6 << endl;
    cout << "Token for object B1 = " << refB1 << endl;
    cout << "Token for object B2 = " << refB2 << endl;
+   cout << "Token for object B3 = " << refB3 << endl;
+   cout << "Token for object C1 = " << refC1 << endl;
+   cout << "Token for object C2 = " << refC2 << endl;
+   cout << "Token for object C3 = " << refC3 << endl;
 
 
    // ===============    READ back
@@ -179,8 +213,13 @@ int main() {
    };
    
    readfun(refA1);   cout << "read back A1: " << readString << endl;
+   readfun(refA7);   cout << "read back A7: " << readString << endl;
+   readfun(refC3);   cout << "read back C3: " << readString << endl;
    readfun(refB1);   cout << "read back B1: " << readString << endl;
+   readfun(refC2);   cout << "read back C2: " << readString << endl;
    readfun(refA3);   cout << "read back A3: " << readString << endl;
+   readfun(refC1);   cout << "read back C1: " << readString << endl;
+   readfun(refB3);   cout << "read back B3: " << readString << endl;
    readfun(refA6);   cout << "read back A6: " << readString << endl;
    readfun(refA4);   cout << "read back A4: " << readString << endl;
    readfun(refB2);   cout << "read back B2: " << readString << endl;
diff --git a/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h b/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h
index d4f76404182999e7621f0f77d445a9ac19fb47ec..5e706f67be59fe3119e99fc5e2f89e7b73d628fc 100644
--- a/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h
+++ b/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -118,8 +118,13 @@ namespace pool    {
     virtual void setSections(const Sections& sections) { m_sections = sections; }
     /// Size of the container
     virtual long long int size();
+    /// Get container name
+    virtual std::string name() const override
+    { return m_name; }
     /// Number of next record in the container (=size if no delete is allowed)
     virtual long long int nextRecordId();
+    /// Suggest next Record ID for tbe next object written - used only with synced indexes
+    virtual void useNextRecordId(long long int) {};
     /// Close the container and deallocate resources
     virtual DbStatus close();
 
diff --git a/Database/APR/StorageSvc/StorageSvc/DbDatabase.h b/Database/APR/StorageSvc/StorageSvc/DbDatabase.h
index df17b9ea4b3e38cb3f5e82008b608cb8ae9697d2..1fe8d35f0e3b01029e5879827fc068a69266988e 100644
--- a/Database/APR/StorageSvc/StorageSvc/DbDatabase.h
+++ b/Database/APR/StorageSvc/StorageSvc/DbDatabase.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -190,8 +190,8 @@ namespace pool  {
     /// Access local container token (if container exists)
     const Token* cntToken(const std::string& cntName);
     /// Allow access to all known containers
-    DbStatus containers(std::vector<const Token*>& conts, 
-                        bool intern=false);
+    DbStatus containers(std::vector<const Token*>& conts, bool intern=false);
+    DbStatus containers(std::vector<IDbContainer*>& conts, bool intern=false);
     /// Allow access to all known associations between containers
     DbStatus associations(std::vector<const Token*>& assocs);
     /// Allow access to all known shapes used by the database
diff --git a/Database/APR/StorageSvc/StorageSvc/IDbContainer.h b/Database/APR/StorageSvc/StorageSvc/IDbContainer.h
index b1b70fd9b22a38a6a07257a478c65f6c53af2015..5f993ac03cb1f7ceea99f3f00753405b1b725b37 100644
--- a/Database/APR/StorageSvc/StorageSvc/IDbContainer.h
+++ b/Database/APR/StorageSvc/StorageSvc/IDbContainer.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: IDbContainer.h 726071 2016-02-25 09:23:05Z krasznaa $
@@ -58,6 +58,8 @@ namespace pool    {
     virtual void release() = 0;
     /// Access to container size
     virtual long long int size() = 0;
+    /// Get container name
+    virtual std::string name() const = 0;
     /// Ask if a given shape is supported
     virtual DbStatus isShapeSupported(const DbTypeInfo* typ) const = 0;
     /// Set options
@@ -79,6 +81,8 @@ namespace pool    {
 
     /// Number of next record in the container (=size if no delete is allowed)
     virtual long long int nextRecordId() = 0;
+    /// Suggest next Record ID for tbe next object written - used only with synced indexes
+    virtual void useNextRecordId(long long int) = 0;
 
     /// Close the container
     virtual DbStatus close() = 0;
diff --git a/Database/APR/StorageSvc/StorageSvc/Transaction.h b/Database/APR/StorageSvc/StorageSvc/Transaction.h
index 6a0de763e1bfba13775bb16a8fd5eec004f456df..6f840602217a9a8dbe0090e0a28cf6ca9a0bd39a 100644
--- a/Database/APR/StorageSvc/StorageSvc/Transaction.h
+++ b/Database/APR/StorageSvc/StorageSvc/Transaction.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -65,6 +65,10 @@ namespace pool  {
     virtual Action state() const = 0;
     /// Access to the transaction type
     virtual Type type() const = 0;
+
+    /// Translate Action to string
+    static const char* actionAsString(Action action);
+ 
   };
 }       // End namespace pool
 #endif  // POOL_TRANSACTION_H
diff --git a/Database/APR/StorageSvc/StorageSvc/pool.h b/Database/APR/StorageSvc/StorageSvc/pool.h
index b8a6a5f3d91cf44116bf78687823eb0694cda211..6f279a00293e16c43d1a2280231fdf8e4e4875ee 100644
--- a/Database/APR/StorageSvc/StorageSvc/pool.h
+++ b/Database/APR/StorageSvc/StorageSvc/pool.h
@@ -2,7 +2,6 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: pool.h 590734 2014-04-01 21:49:36Z gemmeren $
 //====================================================================
 //
 //  Package    : StorageSvc (The pool framework)
@@ -96,7 +95,7 @@ namespace pool   {
   /// Check for tracing
   bool      doTrace();
 
-  /// Translate acce mode to string
+  /// Translate access mode to string
   const char* accessMode(pool::DbAccessMode access_mode);
 
   /// Delete a pointer
diff --git a/Database/APR/StorageSvc/src/DbDatabase.cpp b/Database/APR/StorageSvc/src/DbDatabase.cpp
index b9175480d602a0ef7c002ca1f1342cbc2cfd1fb3..9310ca26a31cf1734181cc49fdaf3a5bfb89c6f6 100644
--- a/Database/APR/StorageSvc/src/DbDatabase.cpp
+++ b/Database/APR/StorageSvc/src/DbDatabase.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -206,6 +206,10 @@ const Token* DbDatabase::cntToken(const string& cntName)
 DbStatus DbDatabase::containers(vector<const Token*>& conts,bool with_internal)
 {  return isValid() ? ptr()->containers(conts,with_internal) : Error;   }
 
+/// Allow access to all known containers
+DbStatus DbDatabase::containers(vector<IDbContainer*>& conts,bool with_internal)
+{  return isValid() ? ptr()->containers(conts,with_internal) : Error;   }
+
 /// Allow access to all known associations between containers
 DbStatus DbDatabase::associations(vector<const Token*>& assocs)
 {  return isValid() ? ptr()->associations(assocs) : Error;              }
diff --git a/Database/APR/StorageSvc/src/DbDatabaseObj.cpp b/Database/APR/StorageSvc/src/DbDatabaseObj.cpp
index af959406746f5a365b255440c9ec0d6ab5ab0b12..a99121100f2657f3e08211031ef4e2b863ede456 100644
--- a/Database/APR/StorageSvc/src/DbDatabaseObj.cpp
+++ b/Database/APR/StorageSvc/src/DbDatabaseObj.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -24,6 +24,7 @@
 #include "StorageSvc/DbReflex.h"
 #include "StorageSvc/DbColumn.h"
 #include "StorageSvc/DbTypeInfo.h"
+#include "StorageSvc/DbOption.h"
 #include "StorageSvc/IOODatabase.h"
 #include "StorageSvc/IDbDatabase.h"
 #include "StorageSvc/IDbContainer.h"
@@ -863,6 +864,23 @@ DbStatus DbDatabaseObj::containers(vector<const Token*>& conts,bool with_interna
   return Error;
 }
 
+/// Allow access to all known containers
+DbStatus DbDatabaseObj::containers(vector<IDbContainer*>& conts,bool with_internals)  {
+  conts.clear();
+  if ( 0 == m_info ) open();
+  if ( 0 != m_info )    {
+     for (iterator i=begin(); i != end(); ++i )    {
+        DbContainerObj* c = (*i).second;
+        if( c == m_links.ptr() || c == m_params.ptr() || c == m_shapes.ptr() )
+           if( not with_internals) continue;
+        if( c->info() ) conts.push_back( c->info() );
+     }
+     return Success;
+  }
+  return Error;
+}
+
+
 /// Access local container token (if container exists)
 const Token* DbDatabaseObj::cntToken(const string& cntName)  {
   if ( 0 == m_info ) open();
diff --git a/Database/APR/StorageSvc/src/DbDatabaseObj.h b/Database/APR/StorageSvc/src/DbDatabaseObj.h
index 46765b73d85cf5e130f81a81378e000b00057d1f..27b43ac8920fc91a2a5e5113c991a3de34e78eb9 100644
--- a/Database/APR/StorageSvc/src/DbDatabaseObj.h
+++ b/Database/APR/StorageSvc/src/DbDatabaseObj.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //====================================================================
@@ -72,6 +72,9 @@ namespace pool    {
     typedef std::map< Guid , const DbTypeInfo* >     ShapeMap;
     /// Definition of map with index elements
     typedef std::map< long long int , int >          IndexMap;
+    /// Base class convenience typdef
+    typedef DbAccessObj<std::string, DbContainerObj > Base;
+     
     /// Handle to domain
     DbDomain                      m_dom;
     /// Handle to link container
@@ -171,8 +174,8 @@ namespace pool    {
     /// Access local container token (if container exists)
     const Token* cntToken(const std::string& cntName);
     /// Allow access to all known containers
-    DbStatus containers(std::vector<const Token*>& conts,
-                      bool intern);
+    DbStatus containers(std::vector<const Token*>& conts, bool intern);
+    DbStatus containers(std::vector<IDbContainer*>& conts, bool intern);
     /// Allow access to all known associations between containers
     DbStatus associations(std::vector<const Token*>& conts);
     /// Allow access to all known shapes used by the database
diff --git a/Database/APR/StorageSvc/src/Transaction.cpp b/Database/APR/StorageSvc/src/Transaction.cpp
index b244402651990816abbcfca4959d749abd1d320c..532452bb14a366872c90242f7462ff91c563c155 100644
--- a/Database/APR/StorageSvc/src/Transaction.cpp
+++ b/Database/APR/StorageSvc/src/Transaction.cpp
@@ -1,8 +1,7 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
-//  $Header: /cvs/PF/pool/StorageSvc/src/Transaction.cpp,v 1.7 2007/11/20 16:43:10 frankb Exp $
 //  ====================================================================
 //  Transaction.cpp
 //  --------------------------------------------------------------------
@@ -30,3 +29,16 @@ Transaction& Transaction::operator=(const Transaction& c)  {
 bool Transaction::operator==(const Transaction& /* c */ ) const  {
   return false;
 }
+
+/// Translate Action to string
+const char* Transaction::actionAsString(Action action) {
+   switch(action) {
+    case TRANSACT_START    : return "START";
+    case TRANSACT_ACTIVE   : return "ACTIVE";
+    case TRANSACT_COMMIT   : return "COMMIT";
+    case TRANSACT_FLUSH    : return "FLUSH";
+    case TRANSACT_ROLLBACK : return "ROLLBACK";
+    case TRANSACT_ENDED    : return "ENDED";
+   }
+   return "UNDEFINED";
+}
diff --git a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
index c11b00f8cbac78f8a7fa05ae1e88ceac9d6d9761..125635fd87ada22ac6da3ff387f342f04b9cfbfa 100644
--- a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
+++ b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file PoolSvc.cxx
@@ -49,6 +49,11 @@
 #include <cstring> 	// for strcmp()
 #include <sys/stat.h> 	// for struct stat
 #include <algorithm> 	// for STL find()
+#include <ctype.h>
+
+bool isNumber(const std::string& s) {
+   return !s.empty() and ( isdigit(s[0]) or s[0]=='+' or s[0]=='-' );
+}
 
 //__________________________________________________________________________
 StatusCode PoolSvc::initialize() {
@@ -836,7 +841,9 @@ StatusCode PoolSvc::setAttribute(const std::string& optName,
             return(StatusCode::FAILURE);
          }
       }
-      if (data[data.size() - 1] == 'L') {
+      if( !isNumber(data) ) {
+         retError = dbH->technologySpecificAttributes().setAttribute(optName, data.c_str(), objName);
+      } else if( data[data.size() - 1] == 'L' ) {
          retError = dbH->technologySpecificAttributes().setAttribute<long long int>(optName, atoll(data.c_str()), objName);
       } else {
          retError = dbH->technologySpecificAttributes().setAttribute<int>(optName, atoi(data.c_str()), objName);