Database Transactions
Overview
When updating the database in multiple locations, it is often a requirement that an update much be completed in full, as a transaction. If one aspect of the update fails, the update cannot proceed in any of the database locations. This maintains database integrity.
For example, when splitting a shipment, the following updates must all be made in full:
- An existing shipment must exist in the database
- A new shipment must be created in the database
- The new shipment’s database fields must be populated with relevant data from the old shipment, such as the shipping address
- At least one item must be removed from the existing shipment
- That item or items must be added to the new shipment
If any of these updates fails, the shipment should not be split, and none of the updates cannot be made to the database. For example, if an item is removed from an existing shipment but cannot be added to a new shipment,
To deal with scenarios like these, Elastic Path uses Spring JDBC capabilities, specifically TransactionProxyFactoryBean
, to configure database transactions and transaction boundaries.
txProxyTemplate
and txRequiredProxyTemplate
Elastic Path provides two abstract beans for database transactions, txProxyTemplate
and txRequiredProxyTemplate
. Both are defined in the ep-core/src/main/resources/spring/service/service.xml
file. Either bean may be used as a parent for any bean that requires database transactions. You then define Spring database transaction propagation settings for methods within the bean or for the bean itself.
The txRequiredProxyTemplate
bean applies the PROPAGATION_REQUIRED
database transaction configuration setting to all methods. The txProxyTemplate
bean applies propagation settings selectively on a method, and is the recommended parent bean in most cases.
Use txProxyTemplate
when you:
- Add configuration properties to the database transaction configuration of a default bean
- Apply database transaction propagation attributes to some but not all methods of a class
- Apply propagation settings other than
PROPAGATION_REQUIRED
Use txRequiredProxyTemplate
when you:
- Apply the
PROPAGATION_REQUIRED
database transaction propagation setting to all methods of a bean
txProxyTemplate
Defining a bean using Define a bean parented by
txProxyTemplate
Define a
<property>
element with aname
attribute value oftarget
In the
<property>
element, define a bean with aclass
attributeThe value of class must be the package and class name of the bean for which to configure database transactions.
Define the bean’s properties as required
For example, to configure database transactions for the class com.elasticpath.service.rules.impl.CouponServiceImpl
, the bean definition is:
<bean id="couponService" parent="txProxyTemplate">
<property name="target">
<bean class="com.elasticpath.service.rules.impl.CouponServiceImpl">
<property name="couponDao" ref="couponDao"/>
<property name="couponUsageDao" ref="couponUsageDao" />
<property name="couponCodeGenerator" ref="couponCodeGenerator" />
</bean>
</property>
</bean>
Configuring database transaction propagation settings
The definition of txProxyTemplate
includes configuration that uses a pattern-matching to identify which methods must operate within a transaction.
For example, any method starting with the words add
, update
, save
, delete
get a propagation setting of PROPAGATION_REQUIRED
. If required, you can override the default propagation settings or introduce new attributes.
Database transaction propagation settings for one or more methods can be configured in your bean as needed using the transactionAttributes
property.
After defining the bean with a parent of txProxyTemplate
, do the following to configure database transaction propagation settings for a method:
Define a
<property="transactionAttributes">
elementIn the
<property>
element, define a<props>
element with amerge
attribute value of either:true
Specifies that the configuration settings that nest inside this element are merged into the default configuration settings provided by
txProxyTemplate
. In most cases,true
is used.false
Specifies that the configuration settings provided by
txProxyTemplate
are overriden
In the
<props>
element, define one or more<prop>
elements with the following:A
key
attributeThe value must be the name of the method for which to configure database transaction propagation.
The
key
attribute supports wildcard matching using the*
character. For example,<props key="update*">PROPAGATION_REQUIRED</props>
appliesPROPAGATION_REQUIRED
to all methods beginning withupdate
.An element value
In most cases,
PROPAGATION_REQUIRED
is used
For example, the com.elasticpath.service.catalog.impl.ProductXmlServiceImpl
class enforces transactions on the getProductMinimalXml()
method using the following bean definition:
<bean id="productXmlService" parent="txProxyTemplate">
<property name="transactionAttributes">
<props merge="true">
<prop key="getProductMinimalXml">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="target">
<bean class="com.elasticpath.service.catalog.impl.ProductXmlServiceImpl">
<property name="productLookup" ref="productLookup"/>
<property name="categoryLookup" ref="categoryLookup"/>
<property name="beanFactory" ref="coreBeanFactory"/>
</bean>
</property>
</bean>
txRequiredProxyTemplate
Defining a bean using For beans in which all methods must use a PROPAGATION_REQURED
propagation configuration, use txRequiredProxyTemplate
as the parent bean.
To define a bean using txRequiredProxyTemplate
:
Define a bean parented by
txRequiredProxyTemplate
Define a
<property>
element with aname
attribute value oftarget
In the
<property>
element, define a bean with a class attributeThe value of class must be the package and class name of the bean for which to configure database transactions.
Define the bean’s properties as required.
For example, the bean definition to configure database transactions for the class com.elasticpath.sellingchannel.director.impl.CartDirectorServiceImpl
, is:
<bean id="cartDirectorService" parent="txRequiredProxyTemplate">
<property name="target" >
<bean class="com.elasticpath.sellingchannel.director.impl.CartDirectorServiceImpl">
<property name="cartDirector" ref="cartDirector"/>
<property name="shoppingCartService" ref="shoppingCartService"/>
<property name="wishListService" ref="wishListService"/>
<property name="pricingSnapshotService" ref="pricingSnapshotService"/>
</bean>
</property>
</bean>