最近看了看社区的精华贴,知道原来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也数据正常,则两个表都插入数据。
题外话:当软件开发基本上只要熟悉操作手册进行配置,当能力被熟练程度所代替,不知道我们还剩下多少创造力可以发挥了。
分享到:
相关推荐
即使当前存在事务也会挂起)、`NOT_SUPPORTED`(永不启动事务,如果当前存在事务,就挂起)、`NEVER`(永不启动事务,如果当前存在事务,则抛出异常)、`NESTED`(如果当前存在事务,则在一个嵌套事务中运行,否则...
7. `Propagation.NESTED`:如果存在当前事务,那么在嵌套事务内执行。如果不存在,则按`Propagation.REQUIRED`行为处理。 以下是一个使用`@Transactional`注解的例子,展示了如何在Service类中控制事务传播: ```...
7. **NESTED**:如果当前有事务,则创建一个嵌套事务,如果没有,则按REQUIRED行为处理。 **事务的隔离级别** 1. **ISOLATION_DEFAULT**:使用数据库默认的隔离级别,如MySQL的REPEATABLE_READ,Oracle的READ_...
- **嵌套事务支持**:允许在分布式事务中嵌套多层事务,增强了事务处理的灵活性。 - **高性能日志读写**:采用Disruptor框架进行事务日志的异步读写,保证了高性能的同时不影响RPC框架的整体性能。 - **SpringBoot...
- **集成事务管理**:通过Spring的事务管理器与jBPM的事务管理进行集成,确保流程执行的原子性。 - **利用Spring MVC或Spring Boot简化前端集成**:使用Spring的Web框架特性来简化前端与jBPM的交互,提高开发效率...
以cms_content_list为例,首先,每一个标签的声明都是在jeecms-context.xml中进行的, <?xml version="1.0" encoding="UTF-8"?> xsi:schemaLocation=...