一例spring嵌套事務

最近看了看社區的精華貼,知道原來service之間是可以嵌套事務的,前些日子還託同事去網絡查,險些聽信了網上事務只能封裝對DAO一層的操作的說法。 於是開始動手試驗,照新的觀點,只要兩個事務傳播屬性都爲PROPAGATION_REQUIRED即可。

相關文件如下:(JavaEYE的編輯器總是出錯,原來是不支持IE6)

ServiceA 定義:

package ht.business.test;

import ht.business.dao.BusinessDAO;
import ht.business.model.Business;

public class BusinessService {
	private BusinessDAO businessDAO=null;

	/**
	 * @return businessDAO
	 */
	public BusinessDAO getBusinessDAO() {
		return businessDAO;
	}

	/**
	 * @param businessDAO 要設置的 businessDAO
	 */
	public void setBusinessDAO(BusinessDAO businessDAO) {
		this.businessDAO = businessDAO;
	}

	public Business addBusiness(){
		Business b=new Business();
		b.setMaker("12345678901234");//15位合法長度
		businessDAO.save(b);
		return b;
		
	}

}
 

 

Service B 定義:

package ht.workflow.test;



import ht.workflow.dao.WorkTabDAO;
import ht.workflow.model.WorkTab;
import ht.business.model.Business;
import ht.business.test.*;

public class WorkflowService {
	
	private WorkTabDAO workTabDAO=null;
	private BusinessService businessService=null;

	/**
	 * @return businessService
	 */
	public BusinessService getBusinessService() {
		return businessService;
	}

	/**
	 * @param businessService 要設置的 businessService
	 */
	public void setBusinessService(BusinessService businessService) {
		this.businessService = businessService;
	}

	/**
	 * @return workTabDAO
	 */
	public WorkTabDAO getWorkTabDAO() {
		return workTabDAO;
	}

	/**
	 * @param workTabDAO 要設置的 workTabDAO
	 */
	public void setWorkTabDAO(WorkTabDAO workTabDAO) {
		this.workTabDAO = workTabDAO;
	}
	
	public void addWorkTab(){
		
			//調用service A的方法
			Business b=businessService.addBusiness(); 
			WorkTab wt=new WorkTab();
			wt.setWorktabid(ht.util.UuidGenerator.createId());
			wt.setWorkdataid(b.getBusinessid());
			wt.setWorkflowtype("0001");
			//error when wt.setStats("1111111");
			wt.setStatus("1");
		
		     workTabDAO.save(wt);

		
		
	}

}
 

 

 

測試類定義:

package ht;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.dao.DataAccessException;

import ht.workflow.test.*;


public class TestWB {
	private static ApplicationContext ctx;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自動生成方法存根
		String[] paths = {"D:/eclipse/workspace/htoa/htioas/WEB-INF/transContext.xml"};
		ctx = new FileSystemXmlApplicationContext(paths);
		WorkflowService wfs=(WorkflowService)ctx.getBean("workflowManager");
		try{
	    wfs.addWorkTab();
		}catch(DataAccessException e){
			e.printStackTrace();
			
		}
		

	}

}
 

 

 

applicationcontext.xml定義:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
	

		<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName"
		value="oracle.jdbc.driver.OracleDriver">
		</property>
		<property name="url"
		value="jdbc:oracle:thin:@192.168.1.7:1521:htioas">
		</property>
		<property name="username" value="htec"></property>
		<property name="password" value="htecioas"></property>
		</bean>

	<bean id="nativeJdbcExtractor"
		class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
		lazy-init="true" />
	<bean id="lobHandler"
		class="org.springframework.jdbc.support.lob.OracleLobHandler"
		lazy-init="true">
		<property name="nativeJdbcExtractor">
			<ref bean="nativeJdbcExtractor" />
		</property>
	</bean>
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="lobHandler">
			<ref bean="lobHandler" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.OracleDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.jdbc.batch_size">50</prop>
				<prop key="hibernate.jdbc.use_streams_for_binary">
					true
				</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				
				
				<!-- BUSINESS workflow begin -->
				<value>ht/business/model/Business.hbm.xml</value>
				
	
				<value>ht/workflow/model/WorkTab.hbm.xml</value>
	
				
			</list>
		</property>
	</bean>

	


	 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	    <property name="sessionFactory" ref="sessionFactory"/>
	 </bean>
		
	<bean id="workflowProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  lazy-init="true">
	    <property name="transactionManager">
		<ref bean="transactionManager" />
	     </property>
	     <property name="transactionAttributes">
		 <props>
		     <prop key="*">PROPAGATION_REQUIRED</prop>
		</props>
	     </property>
	</bean>
	
	<bean id="businesProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  lazy-init="true">
	    <property name="transactionManager">
		<ref bean="transactionManager" />
	     </property>
	     <property name="transactionAttributes">
		 <props>
		     <prop key="*">PROPAGATION_REQUIRED</prop>
		    
		</props>
	     </property>
	</bean>
	
	<bean id="workflowManager"  parent="workflowProxy" >
	    <property name="target">
	         <ref bean="workflowService"/>    
                     
	    </property> 
	</bean>
	<bean id="businessManager"  parent="businesProxy" >
	    <property name="target">
	         <ref bean="businessService"/>    
                     
	    </property> 
	</bean>
	
	<bean id="workflowService" class="ht.workflow.test.WorkflowService">
	<property name="workTabDAO">
			<ref bean="workTabDAO" />
		</property>
		<property name="businessService">
			<ref local="businessService" />
		</property>
	</bean>
	
	<bean id="businessService" class="ht.business.test.BusinessService">
	<property name="businessDAO">
			<ref bean="businessDAO" />
		</property>
	
	</bean>
	
	<bean id="workTabDAO" class="ht.workflow.dao.WorkTabDAO">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>
	<bean id="businessDAO" class="ht.business.dao.BusinessDAO">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>

</beans>
 

 

 

目的: service A 用來向business表插入一條記錄 .

service B 調用service A 向business表插入一條記錄後,再向worktab表插入一條記錄。

若service A異常,事務回滾,兩個表都沒有數據。

若service A正常執行,但在向worktab表插入數據時候異常,整個事務回滾,兩個表仍然都沒有插入數據。

若service A正常執行,後面插入worktab也數據正常,則兩個表都插入數據。

 

 

題外話:當軟件開發基本上只要熟悉操作手冊進行配置,當能力被熟練程度所代替,不知道我們還剩下多少創造力可以發揮了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章