異なる Bean の異なるトランザクションセマンティクスの構成

多数のサービスレイヤーオブジェクトがあり、それぞれにまったく異なるトランザクション構成を適用するシナリオを考えます。これは、異なる pointcut および advice-ref 属性値を持つ個別の <aop:advisor/> エレメントを定義することにより可能です。

比較のポイントとして、最初にすべてのサービス層クラスがルート x.y.service パッケージで定義されていると仮定します。そのパッケージ(またはサブパッケージ)で定義されたクラスのインスタンスであり、名前が Service で終わるすべての Bean にデフォルトのトランザクション構成を持たせるには、次のように記述できます。

<?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
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx
		https://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/aop
		https://www.springframework.org/schema/aop/spring-aop.xsd">

	<aop:config>

		<aop:pointcut id="serviceOperation"
				expression="execution(* x.y.service..*Service.*(..))"/>

		<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>

	</aop:config>

	<!-- these two beans will be transactional... -->
	<bean id="fooService" class="x.y.service.DefaultFooService"/>
	<bean id="barService" class="x.y.service.extras.SimpleBarService"/>

	<!-- ... and these two beans won't -->
	<bean id="anotherService" class="org.xyz.SomeService"/> <!-- (not in the right package) -->
	<bean id="barManager" class="x.y.service.SimpleBarManager"/> <!-- (doesn't end in 'Service') -->

	<tx:advice id="txAdvice">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>

	<!-- other transaction infrastructure beans such as a TransactionManager omitted... -->

</beans>

次の例は、まったく異なるトランザクション設定で 2 つの異なる Bean を構成する方法を示しています。

<?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
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx
		https://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/aop
		https://www.springframework.org/schema/aop/spring-aop.xsd">

	<aop:config>

		<aop:pointcut id="defaultServiceOperation"
				expression="execution(* x.y.service.*Service.*(..))"/>

		<aop:pointcut id="noTxServiceOperation"
				expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>

		<aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>

		<aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>

	</aop:config>

	<!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) -->
	<bean id="fooService" class="x.y.service.DefaultFooService"/>

	<!-- this bean will also be transactional, but with totally different transactional settings -->
	<bean id="anotherFooService" class="x.y.service.ddl.DefaultDdlManager"/>

	<tx:advice id="defaultTxAdvice">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>

	<tx:advice id="noTxAdvice">
		<tx:attributes>
			<tx:method name="*" propagation="NEVER"/>
		</tx:attributes>
	</tx:advice>

	<!-- other transaction infrastructure beans such as a TransactionManager omitted... -->

</beans>