Basics: Transactions

If you are a beginner Revit API hacker, you shouldn't be afraid to explore Revit API. You won't change anything by accident.

Whenever you make changes with Revit API you need to use 🔓Transaction. If you don't, you will encounter an error message saying 'Attempt to modify project without Transaction'.

And this is great news for beginners. It means you don't have to be afraid to mess something up when you explore Revit API.

Why we need Transactions?

Transaction Class in Revit API is like a guardian of your projects. It makes sure that you can only make changes that are on purpose, and nothing is changed by accident.

This is great news for beginners as you don't have to be afraid to explore Revit API.

Many are afraid to try anything new with Revit API on the live projects, and it's good protective measure for sure, but also know you can't mess it up by accident.

Regular Transaction

Transactions are very simple to use. You have to create a transaction by providing:

  • doc - The project where you make changes

  • change-name - Text shown in the Undo menu of Revit

And here is how it looks

#🟠 Regular Transaction
t = Transaction(doc, 'Change-Name')
t.Start() #🔓

# Changes Here...

t.Commit() #🔒


Regular Transaction as Context manager

You can also use Context-Manager in case this makes it better for you in terms of readability. It's the same outcome.

#🟠 Regular Transaction as Context-Manager
with Transaction(doc, 'Change-Name') as t:
    t.Start() #🔓

    #Changes Here

    t.Commit() #🔒


Add Try/Except

It's recommended to use Try/Except statements with your transactions so you can catch any errors and decide what you want to do. It's great for finished tools to suppress a huge wall of red text if you get an error. But you still need to report on it so you can fix it ASAP.

#🟠 Regular Transaction + Try/Except
try:
    t = Transaction(doc, 'Change-Name')
    t.Start()  #🔓
  
    # Changes Here...
  
    t.Commit() #🔒
  
except:
    print('Error Has Occured:')
    import traceback
    print(traceback.format_exc())

Sub-Transaction

You can also use Sub-Transactions but they have a bit different use-case.

Firstly, keep in mind that they can exist only inside of started Transactions, they can't exist on their own. And they are meant to create additional checks before you fully commit.

For Example, Imagine that you create sheets and then you want to place views on them. You might want to first create a sheet, and then check if you can create a viewport with selected view. And sub-transaction can allow you to create Sheet, make a check and then decide if you want to commit creating last sheet or not.


Here is Syntax for SubTransactions:

#🟠 Sub-Transactions can only exist inside regular Transaction
t = Transaction(doc, 'Change-Name')
t.Start()

# Changes Can be Here...

st1 = SubTransaction(doc)
st1.Start()
# Changes Can be Here...
st1.Commit()

# Changes Can be Here...


st2 = SubTransaction(doc)
st2.Start()
# Changes Can be Here...
st2.Commit()

t.Commit()

TransactionGroup

You can also use TransactionGroup and it's meant to combine multiple Transactions.

If Sub-Transaction is children of existing Transaction, TransactipGroup is a parent for multiple Transactions.

I mainly use it when I need to create multiple Transactions and I don't want to have multiple actions in the Undo menu in Revit, so I group them and use Assimilate method to combine everything into single change in the undo menu in Revit UI.

Here is the sample code:

#🟠 TransactionGroup - Combine Multiple Transactions

tg = TransactionGroup(doc, "Change-Name")
tg.Start()


t1 = Transaction(doc, 'Change A')
t1.Start()
# Changes here
t1.Commit()

t2 = Transaction(doc, 'Change B')
t2.Start()
# Changes here
t2.Commit()

tg.Assimilate() # Combine All Transacitons into one

⌨️ Happy Coding!
Erik Frits