但使用Hibernate或沒有container的架構中,transaction不是來自Hibernate session就是JDBC connection(事實上是同一個啦),所以若要將transaction boundaries延伸到Business Layer,勢必變成Business Layer會看到Hibernate session,這又是我們不願意見到的。
但有了Spring AOP之後,這問題似乎可以解決了。
<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="save*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="load*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> <!-- SystemService --> <tx:method name="login" propagation="REQUIRED" rollback-for="Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="allServiceMethods" expression="execution(* com.xxx.service.*Service.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods"/> </aop:config>
首先,透過allServiceMethods規範所有的Business Layer method都必須經過txAdvice定義的transactionManager。
<aop:pointcut id="allServiceMethods" expression="execution(* com.xxx.service.*Service.*(..))"/>表示在com.xxx.service這個package下名稱為Service結尾的所有class的所有method。
<tx:advice id="txAdvice" transaction-manager="transactionManager">...</tx:advice>定義了以method name為規則的transaction條件。
最後用<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods"/>將上面兩項綁起來。
沒有留言:
張貼留言