Spring事務配置方式


Springプロファイルでは、事務構成に関しては、常にDataSource、Transation Manager、プロキシ機構の3つの部分がありますが、どのような構成であっても、一般的にはプロキシ機構の部分だけが変わります.
DataSource、Transaction Managerの2つの部分は、データのアクセス方法によってのみ変化します.例えば、ハイビスカスを使ってデータのアクセスを行う場合、DataSourceは実際にSession Factoryであり、Transactionagerは、ハイビスカスTransation Managerとして実現されます.
プロキシ機構によって五つのSpringトランザクションの構成をまとめました.構成ファイルは以下の通りです.
第一の方法:各Beanには代理があります.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" 
value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>
    <!--        (      ) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!--   DAO -->
    <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <bean id="userDao"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
           <!--         -->
           <property name="transactionManager" ref="transactionManager" />
        <property name="target" ref="userDaoTarget" />
        <property name="proxyInterfaces" value="com.bluesky.spring.dao.GeneratorDao" />
        <!--        -->
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
</beans>
第二の方法:すべてのBeanは一つのエージェントベースクラスを共有する.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" 
value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean> 
    <!--        (      ) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <bean id="transactionBase"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
            lazy-init="true" abstract="true">
        <!--         -->
        <property name="transactionManager" ref="transactionManager" />
        <!--        -->
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    <!--   DAO -->
    <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <bean id="userDao" parent="transactionBase" >
        <property name="target" ref="userDaoTarget" />
    </bean>
</beans>
第三の方式:スクリーンセーバーを使う
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" 
value="org.hibernate.cfg.AnnotationConfiguration" />
	</bean>
    <!--        (      ) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <bean id="transactionInterceptor"  
        class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager" />
        <!--        -->
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <list>
                <value>*Dao</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>transactionInterceptor</value>
            </list>
        </property>
    </bean>
    <!--   DAO -->
    <bean id="userDao" class="com.bluesky.spring.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>
Beanname AutoProxyCreatorを使用して、Bean nameによって自動的に事務代理を生成する方式は、SpringのAOPフレームを直接利用して事務代理を配置する方式であり、SpringのAOPフレームを理解する必要があります.しかし、この方法はインクリメンタル構成を回避し、効果は非常に良いです.
第四の方法:txタグで構成されるスクリーンセーバー
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <context:annotation-config />
    <context:component-scan base-package="com.bluesky" />
    <bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" 
value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>
    <!--        (      ) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="interceptorPointCuts"
            expression="execution(* com.bluesky.spring.dao.*.*(..))" />
        <aop:advisor advice-ref="txAdvice"
            pointcut-ref="interceptorPointCuts" />
    </aop:config>      
</beans>
第五の方法:全注
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <context:annotation-config />
    <context:component-scan base-package="com.bluesky" />
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>
    <!--        (      ) -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>
この時DAOに@Transationコメントを追加します.以下の通りです.

import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;
@Transactional
@Component("userDao")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
    public List<User> listUsers() {
        return this.getSession().createQuery("from User").list();
}
………………
}
第一の方式は第二の方式と類似しています.すべての方式では、第一の方式で書くべきプロファイルが一番多いです.
Spring 2.0では、一般的に方式3を採用していますが、主に配置ファイルの量が小さくなるというメリットがあります.
Spring 2.5の時に、方式5を採用することができます.これで基本的に0配置ができます.