サンプルアプリケーションは、データベースのトランザクション処理ができていない。
こんなアプリケーションが許されるわけはないので、トランザクションを実装しなければならない。
トランザクションはどのように実装するのか。
やり方としては、コンポーネント内の指定した関数を丸ごとトランザクション処理するというイメージになる。
shopping.model.CartProcess の transfer.TransferFactory を AutoWire したタイミングで、transfer.TransferFactory から transfer.com.sql.transaction.Transaction を取得する。
<cffunction name="setOrmService" access="public" returntype="void" output="false">
<cfargument name="ormService" type="transfer.TransferFactory" required="true">
<cfset variables.transfer = arguments.ormService.getTransfer() />
<cfset variables.transaction = arguments.ormService.getTransaction() />
</cffunction>
その Transaction を利用して、
<cfset transaction.execute(component, methodName, [arguments]) />
と、直接的に関数をトランザクション指定で起動することもできる。
直接指定の場合は、その関数を利用するときに、上記の記述で利用することになる。
また、AOPのように記述して、関数を指定することで、指定した関数が丸ごとトランザクション処理されるようだ。
この記述の場合は、事前に行っておくことで、その関数を通常のように利用した場合でも、トランザクション処理されることになる。
<cffunction name="setOrmService" access="public" returntype="void" output="false">
<cfargument name="ormService" type="transfer.TransferFactory" required="true">
<cfset variables.transfer = arguments.ormService.getTransfer() />
<cfset variables.transaction = arguments.ormService.getTransaction() />
<cfset variables.transaction.advise(this, insertItem) />
</cffunction>
さらに、
<cfset arguments.transaction.advise(this, "^save") />
と、正規表現で一括してトランザクション処理指定もできる。
トランザクションで処理したい関数を save で始まる関数名にしておけば、簡単に一括指定できる。