Defining a Transaction Annotation
To solve the problem, you can apply a transaction aspect using AspectWerkz 2.0. First, you must create an interface that serves to denote methods as transactional. This interface will also define a propagation type. While you could specify a particular propagation type (such as
mandatory,
requires new, etc.), for this example the mere presence of the transaction annotation will mark a method as transactional; thus, this attribute is purely for demonstration.
package com.devx.ticketbroker.annotation;
public interface Transaction
{
public String propagationType();
}
Next, declare that the
purchaseTicket method requires a transaction by adding the following javadoc comment to the TicketService.
...
/**
* @transaction(propagationType="required")
*/
public void purchaseTicket(int customerAccountID, int eventID,
int quantity)
{
reserveSeats(eventID, quantity);
chargeCustomerAccount(customerAccountID, eventID, quantity);
}
...
The preceding example shows the use of a named parameter. But because
propagationType is the only parameter it seems unnecessary to have to specify its name. You can instead use an anonymous parameter as illustrated below. For this to work, though, you will have to rename the
propagationType method in the Transaction interface to "value" as shown below:
package com.devx.ticketbroker.annotation;
public interface Transaction
{
public String value();
}
After doing that, here's the revised TicketService annotation.
...
/**
* @transaction("required")
*/
public void purchaseTicket(int customerAccountID, int eventID,
int quantity)
{
reserveSeats(eventID, quantity);
chargeCustomerAccount(customerAccountID, eventID, quantity);
}
...
Lastly, invoke the AnnotationC compiler as a part of the build process to compile javadoc style annotations into the produced class files:
...
<target name="annotationc" depends="compile">
<annotationc verbose="false"
destdir="${project.build.outputDirectory}"
properties=
"${project.build.outputDirectory}/annotation.properties">
<classpath>
<dirset dir="${project.build.outputDirectory}" />
<dirset dir="${project.build.testOutputDirectory}" />
<path refid="dependency.classpath" />
</classpath>
<src path="${project.build.sourceDirectory}" />
<src path="${project.build.testSourceDirectory}" />
</annotationc>
</target>
...