ブログ/本で言及されているように(たとえば、MarkRichardsによるJavaTransactions Design Strategies)、読み取り操作にはPropagation.SUPPORTS属性が必要です。
Hibernate4.1を使用した単純なSpring3.1MVCプロジェクトでは、シナリオは次のとおりです。
- @Transactionalを使用した宣言型トランザクション管理
- org.springframework.orm.hibernate4.LocalSessionFactoryBeanのsessionFactory
- org.springframework.orm.hibernate4.HibernateTransactionManagerのトランザクションマネージャー
- @Transactional(propagation = Propagation.REQUIRED)を使用したサービスクラス
- @Transactional(propagation = Propagation.SUPPORTS)を使用して結果セットのみを取得する(読み取り操作を実行する)サービスクラスの関数
- 読み取り操作の関数は、sessionFactory.getCurrentSession()。get()を使用して結果セットを再結合します
もちろん、コントローラーが読み取り操作の機能を実行すると、トランザクションが開始されず、セッションが取得されないため、「現在のスレッドのセッションが見つかりません」という例外が発生します。
上記の構成に基づいて(たとえば、非侵襲的、コードが少ないなど)、Propagation.SUPPORTS属性は、トランザクションがPropagation.REQUIREDまたはPropagation.REQUIRES_NEWで前に開始されない限り使用できません。
たとえばPropagation.REQUIREDを使用してトランザクションを開始することなく、読み取り操作にPropagation.SUPPORTSを使用するにはどうすればよいですか?ただし、宣言型トランザクション管理の利点を活用しますか?
前もって感謝します。
コーダー、構成は次のとおりです。
<tx:annotation-driven transaction-manager="txManager"/>
<context:component-scan base-package="com.myapps.service.impl" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>.....</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>