最近看了看社区的精华贴,知道原来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也数据正常,则两个表都插入数据。
题外话:当软件开发基本上只要熟悉操作手册进行配置,当能力被熟练程度所代替,不知道我们还剩下多少创造力可以发挥了。
分享到:
相关推荐
spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码
springboot mybatis多数据源加事务嵌套 事务之间的调用 回滚 亲测可用 定义2个库分别建立 CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户编号', `user_name` varchar(25) ...
Java高级编程 实验报告 spring 声明事务 实验目的 掌握spring 声明式事务管理配置 实验环境 本实验采用本实验采用的eclipse或者 Myeclpse开发工具。Spring 4.0以上 Jdk1.7以上、oracle/mysql。
spring声明事务的配置 spring声明事务的配置 spring声明事务的配置
Spring中事务的传播属性详解,Spring中事务的传播属性详解
Spring事务管理Demo
spring事务与数据库操作
Spring事务实践 事务锁 嵌套事务设计原理
Spring的事务配置的五种方式 Spring的事务配置的五种方式 Spring的事务配置的五种方式 Spring的事务配置的五种方式
什么是Spring事务传播机制 Spring事务传播机制是指在多个事务操作发生时,如何管理这些操作之间的事务关系。...NESTED:如果当前存在事务,则在嵌套事务中执行;如果当前没有事务,则创建一个新事务
Spring+Hibernate 使用TransactionInterceptor声明式事务配置
Spring的事务框架将开发过程中事务管理相关的关注点进行适当的分离,并对这些关注点进行合 理的抽象,最终打造了一套使用方便,却功能强大的事务管理“利器”。通过Spring的事务框架,我 们可以按照统一的编程模型来...
Spring事务流程图时序图Spring事务流程图时序图Spring事务流程图时序图Spring事务流程图时序图
spring事务配置详解 spring事务配置详解
本代码使用H2内存数据库演示spring事务使用,包括编程式事务,声明式事务@Transactional使用,自定义事务事务注解实现自定义事务管理器
通过代码解析spring传播特性,包括 ... 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。需要JDBC3.0以上支持。
spring 事务spring 事务spring 事务spring 事务spring 事务
Spring 声明式事务和Spring 编程式事务
spring事务控制jar包,请网上自寻下载
Spring事务操作示例(四种方式),包含完整代码和数据库文件(基于MySQL,在项目sql文件夹中),可运行,学习Spring事务详见博客:http://blog.csdn.net/daijin888888/article/details/51822257