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.
With ColdFusion ORM, you can manage transactions in the following
two ways:
Using Hibernate transaction: User has full
control and ColdFusion does not intervene. The application has to
flush/close the session and commit/rollback the transaction.
For
more information on transactions, go to the following URL:
http://community.jboss.org/wiki/sessionsandtransactions
Using CFTransaction: ColdFusion manages the transaction.
Since a transaction cannot be distributed (across different data
sources), application must ensure that the changes made in the transaction
affect only one Hibernate session. That is, only one data source.
ColdFusion
allows reading of data from other sessions (data source) in a transaction
but changes must be made in only one session. Multiple dirty sessions at
any time in the transaction can result in exceptions and the transaction
is rolled back. Before transaction begins, all existing sessions
in the request are flushed. The previous session (if any) is reused.
When
the transaction is committed, the dirty session is automatically
flushed (before committing the transaction). When the transaction
is rolled back, the changed session cannot be used any longer because
it can cause rolled back data to get committed later. Therefore,
the session participating in the transaction is cleared when transaction
is rolled back.
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.