Transaction and concurrency

When ORM methods are invoked without any transaction, all the data is committed to the database when the ORM session is flushed. ORM session is flushed when ORMFlush() is called or if autoflush is enabled when the request ends.

This works fine when there is not much concurrency, however in most practical scenarios you would need to use transaction in your application so that the data in your database is always in a consistent state.

A description of transaction is beyond the scope of this document. For more information on transactions, see the hibernate documentation.

To run the ORM methods inside a transaction, they must be inside <cftransaction>. A simple example snippet of using ORM with <cftransaction> is as follows:

<cftransaction> 
    <cfset acct1 = EntityLoad("Account", "101")> 
    <cfset acct2 = EntityLoad("Account", "102")> 
    <cfset acct1.debit(1000)> 
    <cfset acct2.credit(1000)> 
    <cfset EntitySave(acct1)> 
    <cfset EntitySave(acct2)> 
</cftransaction>

Because we have not called commit on the <cftransaction> specifically, it is automatically committed when the <cftransaction> ends.

All <cftransaction> semantics including savepoint, multiple rollbacks, multiple commits, and nested transactions work with ORM. You can also have both queries and ORM in the same <cftransaction>.

When <cftransaction> begins, any existing ORM session is flushed and closed, and a new ORM session is created. The <cftransaction> can be committed or rolled back using appropriate ColdFusion tags in <cftransaction>. When the transaction ends and has not been committed or rolled back explicitly, it is automatically committed and the ORM session is closed. If there is any error inside the transaction, without any exception handling, the transaction is rolled back.

For more details on <cftransaction>, see the CFML Reference Guide.

Note: Even if ORMFlush() is called explicitly inside a <cftransaction> tag, the SQL runs but the data is committed only when the transaction commits.