`
雁行
  • 浏览: 69161 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一例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也数据正常,则两个表都插入数据。

 

 

题外话:当软件开发基本上只要熟悉操作手册进行配置,当能力被熟练程度所代替,不知道我们还剩下多少创造力可以发挥了。

分享到:
评论
3 楼 istone 2012-04-07  
雁行 写道
//调用service A的方法  
   Business b=businessService.addBusiness();   

我觉得你这是一个事务中的两个insert,正如文中的“若service A正常执行,但在向worktab表插入数据时候异常,整个事务回滚,两个表仍然都没有插入数据”,如果是嵌套事务的话,应该Business有数据,WorkTab没数据
START TRANSACTION;

	INSERT INTO Business......;
	
	START TRANSACTION;
	
		INSERT INTO WorkTab.....;
		
	ROLLBACK;

COMMIT;
2 楼 雁行 2012-04-05  
//调用service A的方法  
   Business b=businessService.addBusiness();   
1 楼 istone 2012-03-29  
看来看去,你这里只有一层事务,何来嵌套?

相关推荐

Global site tag (gtag.js) - Google Analytics