最近看了看社区的精华贴,知道原来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事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何...
springboot mybatis多数据源加事务嵌套 事务之间的调用 回滚 亲测可用 定义2个库分别建立 CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户编号', `user_name` varchar(25) ...
当我们在使用 Spring 所提供的事务功能时,如果是仅仅处理单个的事务,是比较容易把握事务的提交与回滚,不过一旦引入嵌套事务后,多个事务的回滚和提交就会变得复杂起来,各个事务之间是如何相互影响的,是一个值得...
#### 一、Spring的声明式事务管理 在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。Spring支持两种类型的事务管理...
在Spring框架中,事务管理是核心特性之一,它允许开发者以声明式或编程式的方式处理事务。本示例“spring 事务传播 demo”将聚焦于Spring的事务传播行为,这是在多个方法调用中控制事务边界的关键概念。下面我们将...
在Spring框架中,事务管理是核心功能之一,它允许开发者以声明式或编程式的方式处理事务边界。在本案例中,我们关注的是Spring中的Nested事务,这是一个相对复杂的特性,但非常有用,特别是在需要子事务处理的场景下...
在Spring框架中,事务管理是核心特性之一,它使得开发者能够在多操作数据库时保持数据的一致性和完整性。本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式...
Spring框架的事务管理机制是在Java开发环境中非常重要的一个组成部分,它能够帮助开发者简化事务处理的复杂度,提高应用程序的一致性和可靠性。Spring事务管理的核心是基于AOP(面向切面编程)来实现的。 **Spring...
Spring声明式事务管理是Spring框架的核心特性之一,它允许开发者在不侵入业务代码的情况下,对应用程序的事务进行管理。这种方式极大地提高了代码的可维护性和灵活性。以下是对Spring声明式事务配置的详细说明: 1....
Spring事务实践 事务锁 嵌套事务设计原理
同时,Spring的事务管理机制是其核心功能之一,支持编程式和声明式两种方式,使得开发者可以方便地控制事务的边界。 其次,Hibernate是Java领域最流行的ORM(Object-Relational Mapping)框架,它简化了数据库操作...
在Spring框架中,事务管理是实现业务逻辑时不可或缺的一部分,它确保了数据的一致性和完整性。Spring提供了多种事务管理方式,其中基于注解的事务管理是近年来常用的模式,因为它简化了代码并提高了可读性。本文将...
其中,Spring的分布式事务管理是其核心特性之一,它允许开发者在分布式系统环境中处理复杂的事务逻辑。本篇将深入探讨Spring如何实现分布式事务,以及涉及到的相关技术。 首先,分布式事务是指在多个数据库或者服务...
Spring事务原理是指Spring框架中的一种机制,用于管理事务,并提供了多种配置方式。事务是指一系列的操作,作为一个整体执行,如果其中某个操作失败,整个事务将回滚。Spring事务原理围绕着两个核心:...
Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一...
Spring是一个广泛应用的Java企业级应用开发框架,它提供了强大的事务管理功能,使得开发者可以方便地控制事务的边界,保证数据的一致性和完整性。 首先,理解事务(Transaction)是数据库操作的基础概念。事务具有...
本文将深入探讨如何利用Ibatis实现一对多关系、批处理、事务管理和与Spring及Struts2的集成。 首先,让我们来看一下“一对多”关系。在数据库设计中,一对多关系很常见,比如一个用户可以有多个订单。在Ibatis中,...
在Spring的XML配置文件中,我们需要定义一个PlatformTransactionManager的bean,指定数据源或者其他事务协调器。然后,可以为需要事务的方法添加@Transactional注解。如果使用的是Spring Boot,通常可以在...