]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Multi push key,value session in a transaction.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 11 Aug 2015 10:05:51 +0000 (12:05 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 11 Aug 2015 10:05:51 +0000 (12:05 +0200)
idl/SALOME_SDS.idl
src/SALOMESDS/CMakeLists.txt
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx [new file with mode: 0644]
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx [new file with mode: 0644]
src/SALOMESDS/SALOMESDS_Transaction.cxx
src/SALOMESDS/SALOMESDS_Transaction.hxx
src/SALOMESDS/SALOMESDS_TrustTransaction.hxx [new file with mode: 0644]
src/SALOMESDS/TestSalomeSDS.py

index ed8b9a39d15945f8d9196765b94b3110cdc01a6a..e0ccd185bb17422a6eaa586b6e05d89aa6f972b7 100644 (file)
@@ -46,11 +46,19 @@ module SALOME
   {
   };
 
-  interface PickelizedPyObjRdExtServer : PickelizedPyObjServer
+  interface PickelizedPyObjRdExtBaseServer : PickelizedPyObjServer
+  {
+  };
+
+  interface PickelizedPyObjRdExtServer : PickelizedPyObjRdExtBaseServer
   {
     PickelizedPyObjRdExtServer invokePythonMethodOn(in string method, in ByteVec args) raises (SALOME::SALOME_Exception);
   };
 
+  interface PickelizedPyObjRdExtInitServer : PickelizedPyObjRdExtBaseServer
+  {
+  };
+
   interface PickelizedPyObjRdWrServer : PickelizedPyObjServer
   {
     void setSerializedContent(in ByteVec newValue) raises (SALOME::SALOME_Exception);
@@ -92,6 +100,11 @@ module SALOME
     PickelizedPyObjRdWrServer getVar() raises (SALOME::SALOME_Exception);
   };
 
+  interface TransactionMultiKeyAddSession : Transaction
+  {
+    void addKeyValueInVarErrorIfAlreadyExistingNow(in SALOME::ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+  };
+
   typedef sequence<Transaction> ListOfTransaction;
 
   interface KeyWaiter
@@ -107,7 +120,7 @@ module SALOME
     Transaction createRdWrVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction addKeyValueInVarHard(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction addKeyValueInVarErrorIfAlreadyExisting(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
-    void addKeyValueInVarErrorIfAlreadyExistingNow(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+    TransactionMultiKeyAddSession addMultiKeyValueSession(in string varName) raises (SALOME::SALOME_Exception);
     Transaction removeKeyInVarErrorIfNotAlreadyExisting(in string varName, in ByteVec keyValue) raises (SALOME::SALOME_Exception);
     TransactionRdWrAccess createWorkingVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception);
index 79ca214dc22f9757becd244ef8800cf1ca108827..3ccdb393de1e4b0add866b2bdad8613ae0a7d68d 100644 (file)
@@ -43,6 +43,7 @@ SET(SalomeSDS_SOURCES
   SALOMESDS_PickelizedPyObjServer.cxx
   SALOMESDS_PickelizedPyObjRdOnlyServer.cxx
   SALOMESDS_PickelizedPyObjRdExtServer.cxx
+  SALOMESDS_PickelizedPyObjRdExtInitServer.cxx
   SALOMESDS_PickelizedPyObjRdWrServer.cxx
   SALOMESDS_Transaction.cxx
   SALOMESDS_KeyWaiter.cxx
index 2b56d86d60581502cd246b4d2eeceb452899e79d..528e2566400f9b1a5898f800af7f5950e892f17c 100644 (file)
@@ -23,6 +23,8 @@
 #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
+#include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx"
+#include "SALOMESDS_TrustTransaction.hxx"
 #include "SALOMESDS_KeyWaiter.hxx"
 #include "SALOMESDS_Transaction.hxx"
 #include "SALOME_NamingService.hxx"
@@ -245,10 +247,10 @@ void DataScopeServerBase::initializePython(int argc, char *argv[])
 
 void DataScopeServerBase::registerToSalomePiDict() const
 {
-  PyObject *mod(PyImport_ImportModule("addToKillList"));
+  PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
   if(!mod)
     return;
-  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));
+  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
   if(!meth)
     { Py_XDECREF(mod); return ; }
   PyObject *args(PyTuple_New(2));
@@ -257,6 +259,7 @@ void DataScopeServerBase::registerToSalomePiDict() const
   PyObject *res(PyObject_CallObject(meth,args));
   Py_XDECREF(args);
   Py_XDECREF(res);
+  Py_XDECREF(meth);
   Py_XDECREF(mod);
 }
 
@@ -359,6 +362,36 @@ void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& var
   varc->decrRef();
 }
 
+void DataScopeServerBase::moveStatusOfVarFromRdExtToRdExtInit(const std::string& varName)
+{
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
+  PickelizedPyObjRdExtServer *varc(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
+  if(!varc)
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtToRdExtInit : var is not a RdExt !");
+  PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
+  PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
+  CORBA::Object_var obj(newVar->activate());
+  SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
+  p.first=obj2; p.second=newVar;
+  varc->decrRef();
+}
+
+void DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName)
+{
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
+  PickelizedPyObjRdExtInitServer *varc(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
+  if(!varc)
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt : var is not a RdExtInit !");
+  PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
+  PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
+  CORBA::Object_var obj(newVar->activate());
+  SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
+  p.first=obj2; p.second=newVar;
+  varc->decrRef();
+}
+
 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
@@ -620,29 +653,12 @@ SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlrea
   return SALOME::Transaction::_narrow(obj);
 };
 
-class TrustTransaction
-{
-public:
-  TrustTransaction():_must_rollback(0),_ptr(0) { }
-  void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); }
-  void operate() { _ptr->perform(); }
-  ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); }
-private:
-  bool *_must_rollback;
-  Transaction *_ptr;
-};
-
-void DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
 {
   checkVarExistingAndDict(varName);
-  TransactionAddKeyValueErrorIfAlreadyExisting ret(this,varName,key,value);
-  {
-    bool mustRollback(true);
-    TrustTransaction t;
-    t.setTransaction(&ret,&mustRollback);
-    t.operate();
-    mustRollback=false;
-  }
+  TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
+  CORBA::Object_var obj(ret->activate());
+  return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
 }
 
 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
index 9a98b8a905c060c474fa36b9645afbda2c2ad1c8..cab0c12bd577c18d3059f0e8bc8782e9665be8f2 100644 (file)
@@ -85,6 +85,8 @@ namespace SALOMESDS
   public:
     void moveStatusOfVarFromRdWrToRdOnly(const std::string& varName);
     void moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName);
+    void moveStatusOfVarFromRdExtToRdExtInit(const std::string& varName);
+    void moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName);
   protected:
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator retrieveVarInternal4(const std::string& varName);
@@ -133,7 +135,7 @@ namespace SALOMESDS
     SALOME::Transaction_ptr createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
     SALOME::Transaction_ptr addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
-    void addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+    SALOME::TransactionMultiKeyAddSession_ptr addMultiKeyValueSession(const char *varName);
     SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key);
     SALOME::TransactionRdWrAccess_ptr createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal);
diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx
new file mode 100644 (file)
index 0000000..608af2d
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
+#include "SALOMESDS_Exception.hxx"
+
+#include <iostream>
+#include <sstream>
+
+using namespace SALOMESDS;
+
+const char PickelizedPyObjRdExtInitServer::ACCESS_REPR[]="RdExtInit";
+
+//! obj is consumed
+PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj),_self_deep_copy(0)
+{
+  _self_deep_copy=DeepCopyPyObj(obj);
+}
+
+PickelizedPyObjRdExtInitServer::~PickelizedPyObjRdExtInitServer()
+{
+  Py_XDECREF(_self_deep_copy);
+}
+
+std::string PickelizedPyObjRdExtInitServer::getAccessStr() const
+{
+  return std::string(ACCESS_REPR);
+}
+
+SALOME::ByteVec *PickelizedPyObjRdExtInitServer::fetchSerializedContent()
+{
+  Py_XINCREF(_self_deep_copy);//because pickelize consume _self_deep_copy
+  return FromCppToByteSeq(pickelize(_self_deep_copy));
+}
+
+PyObject *PickelizedPyObjRdExtInitServer::DeepCopyPyObj(PyObject *pyobj)
+{
+  PyObject *mod(PyImport_ImportModule("copy"));//new value
+  PyObject *meth(PyObject_GetAttrString(mod,"deepcopy"));//new value
+  PyObject *args(PyTuple_New(1));
+  Py_XINCREF(pyobj); PyTuple_SetItem(args,0,pyobj);
+  PyObject *ret(PyObject_CallObject(meth,args));
+  Py_XDECREF(args);
+  Py_XDECREF(meth);
+  Py_XDECREF(mod);
+  return ret;
+}
diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx
new file mode 100644 (file)
index 0000000..d5b7c78
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOMESDS_PICKELIZEDPYOBJRDEXTINITSERVER_HXX__
+#define __SALOMESDS_PICKELIZEDPYOBJRDEXTINITSERVER_HXX__
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOME_SDS)
+
+#include <Python.h>
+
+#include "SALOMESDS_PickelizedPyObjServer.hxx"
+
+namespace SALOMESDS
+{
+  class PickelizedPyObjRdExtInitServer : public PickelizedPyObjServerModifiable, public virtual POA_SALOME::PickelizedPyObjRdExtInitServer
+  {
+  public:
+    PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
+    ~PickelizedPyObjRdExtInitServer();
+  public:
+    std::string getAccessStr() const;
+    SALOME::ByteVec *fetchSerializedContent();
+  private:
+    static PyObject *DeepCopyPyObj(PyObject *pyobj);
+  private:
+    PyObject *_self_deep_copy;
+  public:
+    static const char ACCESS_REPR[];
+  };
+}
+
+#endif
index 964303cfed5ef2ad774ba0a7da1fec48b3f1f2e7..a903cca490388cae93e929603410ad781ed8b48c 100644 (file)
@@ -23,6 +23,7 @@
 #include "SALOMESDS_PickelizedPyObjServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
+#include "SALOMESDS_TrustTransaction.hxx"
 
 #include <sstream>
 
@@ -224,3 +225,49 @@ void TransactionMorphRdWrIntoRdOnly::rollBack()
 void TransactionMorphRdWrIntoRdOnly::notify()
 {
 }
+
+TransactionMultiKeyAddSession::TransactionMultiKeyAddSession(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName)
+{
+  _dsct->moveStatusOfVarFromRdExtToRdExtInit(_var_name);
+}
+
+void TransactionMultiKeyAddSession::addKeyValueInVarErrorIfAlreadyExistingNow(const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+{
+  _dsct->checkVarExistingAndDict(_var_name);
+  TransactionAddKeyValueErrorIfAlreadyExisting ret(_dsct,_var_name,key,value);
+  {
+    bool mustRollback(true);
+    TrustTransaction t;
+    t.setTransaction(&ret,&mustRollback);
+    t.operate();
+    mustRollback=false;//important let this line to notify t that everything was OK
+  }
+  ret.notify();
+}
+
+/*!
+ * no implementation it is not a bug !
+ */
+void TransactionMultiKeyAddSession::prepareRollBackInCaseOfFailure()
+{
+}
+
+void TransactionMultiKeyAddSession::perform()
+{
+  _dsct->moveStatusOfVarFromRdExtInitToRdExt(_var_name);
+}
+
+/*!
+ * no implementation it is not a bug !
+ */
+void TransactionMultiKeyAddSession::rollBack()
+{
+}
+
+/*!
+ * no implementation it is not a bug !
+ */
+void TransactionMultiKeyAddSession::notify()
+{
+}
+
index 4fad07b058cfbf4fb6e1badee507638c5385d44c..8d3db4479a894dc3920997841211006c9dac1175 100644 (file)
@@ -153,6 +153,19 @@ namespace SALOMESDS
     void rollBack();
     void notify();
   };
+
+  class TransactionMultiKeyAddSession : public Transaction, public virtual POA_SALOME::TransactionMultiKeyAddSession
+  {
+  public:
+    TransactionMultiKeyAddSession(DataScopeServerTransaction *dsct, const std::string& varName);
+  public://remotely callable
+    void addKeyValueInVarErrorIfAlreadyExistingNow(const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+  public:
+    void prepareRollBackInCaseOfFailure();
+    void perform();
+    void rollBack();
+    void notify();
+  };
 }
 
 #endif
diff --git a/src/SALOMESDS/SALOMESDS_TrustTransaction.hxx b/src/SALOMESDS/SALOMESDS_TrustTransaction.hxx
new file mode 100644 (file)
index 0000000..52a91ee
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOMESDS_TRUSTTRANSACTION_HXX__
+#define __SALOMESDS_TRUSTTRANSACTION_HXX__
+
+#include "SALOMESDS_Transaction.hxx"
+#include "SALOMESDS_Exception.hxx"
+
+namespace SALOMESDS
+{
+  class TrustTransaction
+  {
+  public:
+    TrustTransaction():_must_rollback(0),_ptr(0) { }
+    void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); }
+    void operate() { _ptr->perform(); }
+    ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); }
+  private:
+    bool *_must_rollback;
+    Transaction *_ptr;
+  };
+}
+
+#endif
index c916d19c29c5f252603c178fde17e2e48cbbaa3e..80557dc58a26731bead3d3f590ca773114c7fdb1 100644 (file)
@@ -213,8 +213,17 @@ class SalomeSDSTest(unittest.TestCase):
     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
     dss.atomicApply([t0])
     #
-    self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExistingNow,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
-    dss.addKeyValueInVarErrorIfAlreadyExistingNow(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
+    self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
+    t1=dss.addMultiKeyValueSession(varName)
+    self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
+    self.assertRaises(SALOME.SALOME_Exception,t1.addKeyValueInVarErrorIfAlreadyExistingNow,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
+    self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
+    wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
+    t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
+    self.assertEqual(str2Obj(wk.waitFor()),[7,8,9,10])
+    self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
+    dss.atomicApply([t1])
+    self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
     #
     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))