FreeCAD Scripting: How to Rollback Transactions
This article explains how to safely discard modifications made by Python scripts in FreeCAD using built-in transaction methods. When automating parametric modeling, scripts can encounter unexpected runtime exceptions or invalid geometries. By wrapping your code in a document transaction, you can ensure that any failing operation cleanly reverts the document to its original state rather than leaving behind orphaned or broken objects.
Understanding FreeCAD Transactions
FreeCAD's Application interface (FreeCAD or
App) provides a transaction mechanism through the active
document. Transactions group multiple modeling commands into an atomic
operation. If the script finishes successfully, the transaction is
committed; if an error occurs, the transaction can be aborted,
effectively rolling back all modifications made since the transaction
was opened.
The primary methods used on the document object are:
openTransaction(name): Starts recording changes under a specified transaction name.commitTransaction(): Finalizes and saves all changes made during the open transaction.abortTransaction(): Discards all changes made during the open transaction and restores the previous state.
Implementation Pattern
The most reliable way to implement transaction rollbacks is with a
standard Python try...except block. This ensures that any
unhandled exception triggers an immediate rollback.
import FreeCAD as App
import Part
doc = App.activeDocument()
if doc is None:
doc = App.newDocument("TransactionDemo")
# 1. Open the transaction
transaction_name = "CreateParametricShape"
doc.openTransaction(transaction_name)
try:
# 2. Perform document operations
box = doc.addObject("Part::Box", "TempBox")
box.Length = 10.0
box.Width = 10.0
box.Height = 10.0
doc.recompute()
# Simulate an error condition
raise RuntimeError("An unexpected error occurred during processing.")
# 3. Commit if everything succeeds
doc.commitTransaction()
print("Transaction committed successfully.")
except Exception as error:
# 4. Abort and rollback on failure
doc.abortTransaction()
print(f"Error encountered: {error}")
print("Transaction aborted. Changes have been rolled back.")
# Ensure document status is updated
doc.recompute()Rolling Back Already Committed Changes
If a transaction has already been committed using
commitTransaction(), calling
abortTransaction() will no longer affect it. To undo
changes after committing, use the document's undo()
method:
# Reverses the last committed transaction
doc.undo()
doc.recompute()Key Considerations
- Nested Transactions: FreeCAD does not natively support nested transactions. Always ensure that an open transaction is either committed or aborted before opening a new one.
- Recompute Timing: Changes aborted with
abortTransaction()instantly remove temporary objects from the internal tree, but callingdoc.recompute()afterward ensures the 3D view and tree view are fully synchronized with the rolled-back state.