diff --git a/product/CMFActivity/tests/testCMFActivity.py b/product/CMFActivity/tests/testCMFActivity.py
index d74cceaaed7195b4685c00641d6f3db615a14163..2cd1380640b7f170ec95d1ff96689d390f9ddc81 100644
--- a/product/CMFActivity/tests/testCMFActivity.py
+++ b/product/CMFActivity/tests/testCMFActivity.py
@@ -312,11 +312,11 @@ class TestCMFActivity(ERP5TypeTestCase):
     portal = self.getPortal()
     def DeferredSetTitle(self,value,commit_sub=0):
       if commit_sub:
-        get_transaction().commit(1)
+        get_transaction().savepoint(optimistic=True)
       self.activate(activity=second or activity,priority=4)._setTitle(value)
     def DeferredSetDescription(self,value,commit_sub=0):
       if commit_sub:
-        get_transaction().commit(1)
+        get_transaction().savepoint(optimistic=True)
       self.activate(activity=second or activity,priority=4)._setDescription(value)
     from Products.ERP5Type.Document.Organisation import Organisation
     Organisation.DeferredSetTitle = DeferredSetTitle
diff --git a/product/ERP5/Extensions/CheckPortalTypes.py b/product/ERP5/Extensions/CheckPortalTypes.py
index cd4d028914439e1f2cbbfa17bbbb889e587ca04f..26d21364f2d8c3d7ea6623a3b2b053241e711fe1 100644
--- a/product/ERP5/Extensions/CheckPortalTypes.py
+++ b/product/ERP5/Extensions/CheckPortalTypes.py
@@ -2,6 +2,7 @@ from Products.ERP5Type.Globals import get_request
 from Acquisition import aq_base
 from Products.ERP5Type.Globals import PersistentMapping
 from Products.CMFCore.utils import getToolByName
+import transaction
 
 
 def fixProductNames(self, REQUEST=None):
@@ -69,7 +70,7 @@ def updateBalanceTransactionClass(self):
     obj = obj.getObject()
     #print 'updating', obj, 'with class', BalanceTransaction
     changeObjectClass(module, obj.getId(), BalanceTransaction)
-    get_transaction().commit(1)
+    transaction.savepoint(optimistic=True)
 
     newobj = getattr(module, obj.getId())
     reverseSourceAndDestination(newobj)
diff --git a/product/ERP5/Extensions/Transaction.py b/product/ERP5/Extensions/Transaction.py
index 3e04cf38d4915e36bd8da7f057fa907dfc7da4a0..05aa4066f9adefb5bdc50096f8c15a737cc8c48d 100644
--- a/product/ERP5/Extensions/Transaction.py
+++ b/product/ERP5/Extensions/Transaction.py
@@ -1,14 +1,9 @@
-# def this_transaction():
-#     return get_transaction()
-# 
-# def commit_transaction():
-#     get_transaction().commit()
+import transaction
 
 def abort_transaction():
-    get_transaction().abort()
-
-# def abort_subtransaction():
-#     get_transaction().abort(1)
-# 
-# def commit_subtransaction():
-#     get_transaction().commit(1)
+    # FIXME: aborting a transaction means it could be commited later on. The
+    # transaction should be doom()ed instead, but transaction.doom() is not
+    # available on Zope 2.8. We should provide our own doom() implementation
+    # which raises an exception on pre-commit-hook, which does exist
+    # in Zope 2.8
+    transaction.abort()
diff --git a/product/ERP5/tests/testERP5Core.py b/product/ERP5/tests/testERP5Core.py
index dcc9ad8ae96d42ced4fc58007f3aca938453b9a2..fdc126bffde2a45976a1756286cb0d6cfeff16ff 100644
--- a/product/ERP5/tests/testERP5Core.py
+++ b/product/ERP5/tests/testERP5Core.py
@@ -315,7 +315,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
                                     uids=uid_list,
                                     md5_object_uid_list=md5_string)
     self.assert_('Deleted.' in redirect, redirect)
-    transaction.commit(1)
+    transaction.savepoint(optimistic=True)
     self.assertEquals(len(module.objectValues()), 0)
 
   def test_Folder_delete_related_object(self):
@@ -339,7 +339,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
                                     uids=uid_list,
                                     md5_object_uid_list=md5_string)
     self.assert_('Sorry, 1 item is in use.' in redirect, redirect)
-    transaction.commit(1)
+    transaction.savepoint(optimistic=True)
     self.assertEquals(len(module.objectValues()), 2)
 
 
@@ -368,7 +368,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
                                     uids=uid_list,
                                     md5_object_uid_list=md5_string)
     self.assert_('Sorry, 1 item is in use.' in redirect, redirect)
-    transaction.commit(1)
+    transaction.savepoint(optimistic=True)
     self.assertEquals(len(module.objectValues()), 2)
 
 
diff --git a/product/ERP5Type/Core/Folder.py b/product/ERP5Type/Core/Folder.py
index dfe58f05b52b883aa75cf1dc4a28c5f36580074f..4e1020f71fd9506a43deb9ad9f7da012a217e0e8 100644
--- a/product/ERP5Type/Core/Folder.py
+++ b/product/ERP5Type/Core/Folder.py
@@ -1026,7 +1026,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn,
           update_list += method_message
         update_list += test_after(o,REQUEST=REQUEST)
       # And commit subtransaction
-      #transaction.commit(1)
+      #transaction.savepoint(optimistic=True)
       transaction.commit() # we may use commit(1) some day XXX
       # Recursively call recursiveApply if o has a recursiveApply method (not acquired)
       obase = aq_base(o)
@@ -1262,7 +1262,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn,
       btree_ok = self._cleanup()
       if not btree_ok:
         # We must commit if we want to keep on recursing
-        transaction.commit(1)
+        transaction.savepoint(optimistic=True)
         error_list += [(self.getRelativeUrl(), 'BTree Inconsistency',
                        199, '(fixed)')]
     # Call superclass
@@ -1270,7 +1270,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn,
     # We must commit before listing folder contents
     # in case we erased some data
     if fixit:
-      transaction.commit(1)
+      transaction.savepoint(optimistic=True)
     # Then check the consistency on all sub objects
     for obj in self.contentValues():
       if fixit:
diff --git a/product/ERP5Type/tests/testCachedSkinsTool.py b/product/ERP5Type/tests/testCachedSkinsTool.py
index c20bf6ddaa56943a1a0d1851350f1d1e3414f2fc..fddb60f93508f6038cb2f1c6b33e7b2a11bd3268 100644
--- a/product/ERP5Type/tests/testCachedSkinsTool.py
+++ b/product/ERP5Type/tests/testCachedSkinsTool.py
@@ -119,7 +119,7 @@ class TestCachedSkinsTool(ERP5TypeTestCase):
     tested_skin_folder.manage_addProduct['OFSP'].manage_addFolder(id=searched_object_id)
     # Commit transaction so that the created object gets a _p_jar, so it can be renamed.
     # See OFS.CopySupport:CopySource.cb_isMoveable()
-    transaction.commit(1)
+    transaction.savepoint(optimistic=True)
     self.getSkinnableObject().changeSkin(skinname=None)
     # Access the object to make sure it is present in cache.
     self.assertTrue(getattr(skinnable_object,   searched_object_id, None) is not None)
diff --git a/product/ERP5Type/tests/testERP5Type.py b/product/ERP5Type/tests/testERP5Type.py
index 185aafe250afa369f20e42962115168182d5f309..8d7815c730d26e6d2b3efe149c8f212bc0abde1a 100644
--- a/product/ERP5Type/tests/testERP5Type.py
+++ b/product/ERP5Type/tests/testERP5Type.py
@@ -561,7 +561,7 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
         folder.newContent(portal_type='Organisation', id=id_)
       # commit a subtransaction, so that we can rename objecs (see
       # OFS.ObjectManager._getCopy)
-      transaction.commit(1)
+      transaction.savepoint(optimistic=True)
 
       for obj in folder.objectValues():
         new_id = '%s_new' % obj.getId()