updated ORM coverage to provide <tx:advice> and @Transactional samples; removed ProxyFactoryBean example
This commit is contained in:
parent
48e7c44c35
commit
c9bcc771dc
|
|
@ -89,7 +89,7 @@ public class SomeMovieFinder implements MovieFinder {
|
|||
<interfacename>@PersistenceContext</interfacename> annotations. Here is an
|
||||
example for a JPA repository:</para>
|
||||
|
||||
<programlisting language="java"><![CDATA[@Repository
|
||||
<programlisting language="java">@Repository
|
||||
public class JpaMovieFinder implements MovieFinder {
|
||||
|
||||
@PersistenceContext
|
||||
|
|
@ -97,12 +97,12 @@ public class JpaMovieFinder implements MovieFinder {
|
|||
|
||||
// ...
|
||||
|
||||
}]]></programlisting>
|
||||
}</programlisting>
|
||||
|
||||
<para>If you are using the classic Hibernate APIs than you can inject the
|
||||
SessionFactory:</para>
|
||||
|
||||
<programlisting language="java"><![CDATA[@Repository
|
||||
<programlisting language="java">@Repository
|
||||
public class HibernateMovieFinder implements MovieFinder {
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
|
@ -114,7 +114,7 @@ public class HibernateMovieFinder implements MovieFinder {
|
|||
|
||||
// ...
|
||||
|
||||
}]]></programlisting>
|
||||
}</programlisting>
|
||||
|
||||
<para>Last example we will show here is for typical JDBC support. You
|
||||
would have the <classname>DataSource</classname> injected into an
|
||||
|
|
@ -123,7 +123,7 @@ public class HibernateMovieFinder implements MovieFinder {
|
|||
like <classname>SimpleJdbcCall</classname> etc using this
|
||||
<classname>DataSource</classname>.</para>
|
||||
|
||||
<programlisting language="java"><![CDATA[@Repository
|
||||
<programlisting language="java">@Repository
|
||||
public class JdbcMovieFinder implements MovieFinder {
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
|
@ -135,6 +135,14 @@ public class JdbcMovieFinder implements MovieFinder {
|
|||
|
||||
// ...
|
||||
|
||||
}]]></programlisting>
|
||||
}</programlisting>
|
||||
|
||||
<note>
|
||||
<para>Please see the specific coverage of each persistence technology
|
||||
for details on how to configure the application context to take
|
||||
advantage of these annotations.</para>
|
||||
</note>
|
||||
|
||||
<para></para>
|
||||
</section>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
|
|
|||
|
|
@ -142,8 +142,8 @@
|
|||
solutions for this issue, sometimes sacrificing proper handling of
|
||||
failures for programming convenience. Spring advocates strikingly simple
|
||||
solutions for proper resource handling, namely IoC via templating in the
|
||||
case of JDBC and applying AOP interceptors for the ORM technologies.
|
||||
</para>
|
||||
case of JDBC and applying AOP interceptors for the ORM
|
||||
technologies.</para>
|
||||
|
||||
<para>The infrastructure cares for proper resource handling, and for
|
||||
appropriate conversion of specific API exceptions to an unchecked
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
<classname>DataAccessException</classname> hierarchy, including
|
||||
translation of database-specific SQL error codes to meaningful exception
|
||||
classes. For ORM technologies, see the next section for how to get the
|
||||
same exception translation benefits. </para>
|
||||
same exception translation benefits.</para>
|
||||
|
||||
<para>When it comes to transaction management the
|
||||
<classname>JdbcTemplate</classname> class hooks in to the Spring
|
||||
|
|
@ -164,7 +164,7 @@
|
|||
technologies Spring offers Hibernate, JPA and JDO support via the
|
||||
Hibernate / JPA / JDO transaction managers as well as JTA support. For
|
||||
more details on the transaction support see the <xref
|
||||
linkend="transaction" /> chapter. </para>
|
||||
linkend="transaction" /> chapter.</para>
|
||||
</section>
|
||||
|
||||
<section id="orm-exception-translation">
|
||||
|
|
@ -382,6 +382,140 @@ public class ProductDaoImpl implements ProductDao {
|
|||
transactions.</para>
|
||||
</section>
|
||||
|
||||
<section id="orm-hibernate-tx-declarative">
|
||||
<title>Declarative transaction demarcation</title>
|
||||
|
||||
<para>We recommended that you use Spring's declarative transaction
|
||||
support, which essentially enables you to replace explicit transaction
|
||||
demarcation API calls in your Java code with an AOP transaction
|
||||
interceptor configured in a Spring container. This allows you to keep
|
||||
business services free of repetitive transaction demarcation code, and
|
||||
allows you to focus on adding business logic which is where the real
|
||||
value of your application lies.</para>
|
||||
|
||||
<note>
|
||||
<para>You are <emphasis>strongly</emphasis> encouraged to read the
|
||||
section entitled <xref linkend="transaction-declarative" /> if you
|
||||
have not done so already prior to continuing.</para>
|
||||
</note>
|
||||
|
||||
<para>Furthermore, transaction semantics like propagation behavior and
|
||||
isolation level can be changed in a configuration file and do not affect
|
||||
the business service implementations.</para>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<lineannotation><!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --></lineannotation>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
|
||||
</aop:config>
|
||||
|
||||
<tx:advice id="txAdvice" transaction-manager="myTxManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="increasePrice*" propagation="REQUIRED"/>
|
||||
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
|
||||
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<bean id="myProductService" class="product.SimpleProductService">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
</bean>
|
||||
|
||||
</beans></programlisting>
|
||||
|
||||
<programlisting language="java">public class ProductServiceImpl implements ProductService {
|
||||
|
||||
private ProductDao productDao;
|
||||
|
||||
public void setProductDao(ProductDao productDao) {
|
||||
this.productDao = productDao;
|
||||
}
|
||||
|
||||
<lineannotation>// notice the absence of transaction demarcation code in this method</lineannotation>
|
||||
<lineannotation>// Spring's declarative transaction infrastructure will be demarcating transactions on your behalf </lineannotation>
|
||||
public void increasePriceOfAllProductsInCategory(final String category) {
|
||||
List productsToChange = this.productDao.loadProductsByCategory(category);
|
||||
<lineannotation>// ...</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>For completenes we will also show an attribute-support based
|
||||
configuration. We annotate the service layer with @Transactional
|
||||
annotations and instruct the Spring container to find these annotations
|
||||
and provide transactional semantics for these annotated methods.</para>
|
||||
|
||||
<programlisting language="java">public class ProductServiceImpl implements ProductService {
|
||||
|
||||
private ProductDao productDao;
|
||||
|
||||
public void setProductDao(ProductDao productDao) {
|
||||
this.productDao = productDao;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void increasePriceOfAllProductsInCategory(final String category) {
|
||||
List productsToChange = this.productDao.loadProductsByCategory(category);
|
||||
<lineannotation>// ...</lineannotation>
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Product> findAllProducts() {
|
||||
return this.productDao.findAllProducts();
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>As you can see from the following configuration example, the
|
||||
configuration is much simplified while still providing the same
|
||||
functionality driven by the annotations in the service layer
|
||||
code.</para>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<lineannotation><!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --></lineannotation>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven/>
|
||||
|
||||
<bean id="myProductService" class="product.SimpleProductService">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
</bean>
|
||||
|
||||
</beans></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="orm-hibernate-tx-programmatic">
|
||||
<title>Programmatic transaction demarcation</title>
|
||||
|
||||
|
|
@ -435,59 +569,6 @@ public class ProductDaoImpl implements ProductDao {
|
|||
);
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section id="orm-hibernate-tx-declarative">
|
||||
<title>Declarative transaction demarcation</title>
|
||||
|
||||
<para>Alternatively, one can use Spring's declarative transaction
|
||||
support, which essentially enables you to replace explicit transaction
|
||||
demarcation API calls in your Java code with an AOP transaction
|
||||
interceptor configured in a Spring container. This allows you to keep
|
||||
business services free of repetitive transaction demarcation code, and
|
||||
allows you to focus on adding business logic which is where the real
|
||||
value of your application lies. Furthermore, transaction semantics like
|
||||
propagation behavior and isolation level can be changed in a
|
||||
configuration file and do not affect the business service
|
||||
implementations.</para>
|
||||
|
||||
<programlisting language="xml"><beans>
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="mySessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces" value="product.ProductService"/>
|
||||
<property name="target">
|
||||
<bean class="product.DefaultProductService">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<value>myTxInterceptor</value> <lineannotation><!-- the transaction interceptor (configured elsewhere) --></lineannotation>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans></programlisting>
|
||||
|
||||
<programlisting language="java">public class ProductServiceImpl implements ProductService {
|
||||
|
||||
private ProductDao productDao;
|
||||
|
||||
public void setProductDao(ProductDao productDao) {
|
||||
this.productDao = productDao;
|
||||
}
|
||||
|
||||
<lineannotation>// notice the absence of transaction demarcation code in this method</lineannotation>
|
||||
<lineannotation>// Spring's declarative transaction infrastructure will be demarcating transactions on your behalf </lineannotation>
|
||||
public void increasePriceOfAllProductsInCategory(final String category) {
|
||||
List productsToChange = this.productDao.loadProductsByCategory(category);
|
||||
<lineannotation>// ...</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>Spring's <classname>TransactionInterceptor</classname> allows any
|
||||
checked application exception to be thrown with the callback code, while
|
||||
|
|
@ -499,55 +580,6 @@ public class ProductDaoImpl implements ProductDao {
|
|||
<classname>TransactionStatus</classname>).
|
||||
<classname>TransactionInterceptor</classname> behaves the same way by
|
||||
default but allows configurable rollback policies per method.</para>
|
||||
|
||||
<para>The following higher level approach to declarative transactions
|
||||
doesn't use the <classname>ProxyFactoryBean</classname>, and as such may
|
||||
be easier to use if you have a large number of service objects that you
|
||||
wish to make transactional.</para>
|
||||
|
||||
<note>
|
||||
<para>You are <emphasis>strongly</emphasis> encouraged to read the
|
||||
section entitled <xref linkend="transaction-declarative" /> if you
|
||||
have not done so already prior to continuing.</para>
|
||||
</note>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
|
||||
|
||||
<lineannotation><!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --></lineannotation>
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="mySessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
|
||||
</aop:config>
|
||||
|
||||
<tx:advice id="txAdvice" transaction-manager="myTxManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="increasePrice*" propagation="REQUIRED"/>
|
||||
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
|
||||
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<bean id="myProductService" class="product.SimpleProductService">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
</bean>
|
||||
|
||||
</beans></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="orm-hibernate-tx-strategies">
|
||||
|
|
@ -633,26 +665,24 @@ public class ProductDaoImpl implements ProductDao {
|
|||
<property name="sessionFactory" ref="mySessionFactory2"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- this shows the Spring 1.x style of declarative transaction configuration --></lineannotation>
|
||||
<lineannotation><!-- it is totally supported, 100% legal in Spring 2.x, but see also above for the sleeker, Spring 2.0 style --></lineannotation>
|
||||
<bean id="myProductService"
|
||||
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="transactionManager" ref="myTxManager"/>
|
||||
<property name="target">
|
||||
<bean class="product.ProductServiceImpl">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
<property name="inventoryDao" ref="myInventoryDao"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
<prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
|
||||
<prop key="someOtherBusinessMethod">PROPAGATION_REQUIRES_NEW</prop>
|
||||
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
|
||||
</props>
|
||||
</property>
|
||||
<bean id"myProductService" class="product.ProductServiceImpl">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
<property name="inventoryDao" ref="myInventoryDao"/>
|
||||
</bean>
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
|
||||
</aop:config>
|
||||
|
||||
<tx:advice id="txAdvice" transaction-manager="myTxManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="increasePrice*" propagation="REQUIRED"/>
|
||||
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
|
||||
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
</beans></programlisting>
|
||||
|
||||
<para>Both <classname>HibernateTransactionManager</classname> and
|
||||
|
|
@ -1078,6 +1108,13 @@ public class ProductDaoImpl implements ProductDao {
|
|||
<para>To execute service operations within transactions, you can use
|
||||
Spring's common declarative transaction facilities. For example:</para>
|
||||
|
||||
<note>
|
||||
<para>You are <emphasis>strongly</emphasis> encouraged to read the
|
||||
section entitled <xref linkend="transaction-declarative" /> if you
|
||||
have not done so to get a more detailed coverage of Spring's
|
||||
declarative transaction support.</para>
|
||||
</note>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
|
|
@ -1086,11 +1123,11 @@ public class ProductDaoImpl implements ProductDao {
|
|||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.jdo.JdoTransactionManager">
|
||||
<property name="persistenceManagerFactory" ref="myPmf"/>
|
||||
|
|
@ -1755,10 +1792,10 @@ public class ProductDaoImpl implements ProductDao {
|
|||
<literal>@PersistenceUnit</literal> and
|
||||
<literal>@PersistenceContext</literal>) can be applied on field or
|
||||
methods inside a class, therefore the expression "method/field level
|
||||
injection". Field-level annotations concise and easier to use while
|
||||
method-level allow for processing the injected dependency. In both
|
||||
cases the member visibility (public, protected, private) does not
|
||||
matter.</para>
|
||||
injection". Field-level annotations are concise and easier to use
|
||||
while method-level allow for further processing of the injected
|
||||
dependency. In both cases the member visibility (public, protected,
|
||||
private) does not matter.</para>
|
||||
|
||||
<para>What about class level annotations?</para>
|
||||
|
||||
|
|
@ -1832,6 +1869,13 @@ public class ProductDaoImpl implements ProductDao {
|
|||
<para>To execute service operations within transactions, you can use
|
||||
Spring's common declarative transaction facilities. For example:</para>
|
||||
|
||||
<note>
|
||||
<para>You are <emphasis>strongly</emphasis> encouraged to read the
|
||||
section entitled <xref linkend="transaction-declarative" /> if you have
|
||||
not done so to get a more detailed coverage of Spring's declarative
|
||||
transaction support.</para>
|
||||
</note>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
|
@ -1839,11 +1883,11 @@ public class ProductDaoImpl implements ProductDao {
|
|||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="myEmf"/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue