您的位置:首页 > 编程语言 > Java开发

Spring嵌套事务的两种事务管理配置方式

2008-11-07 15:57 597 查看
由于系统涉及业务太多,数据管理方面也相当复杂,用Spring实现事务管理的时候,如果采用默认的方式,单独给每个业务的 Service 配置代理 Proxy,务必会使配置工作很繁重,但是使用自动配置事务机制以后,一切工作都会很轻松,包括嵌套事务的实现,也相当轻松,网上流动许多关于Spring事务配置的帖子,但是都很不完全,缺东少西,也给许多爱好者带来不便,下面将这两天的调试结果写下,希望对朋友们有所帮助!

首先,本系统采用的是 业务和事务的并行方式,也就是说 根据现实中的业务来决定事务的大小,尽最大可能避免事务嵌套,但是为了考虑系统的稳定性,把事务配置为支持嵌套的方式!

缺点:测试代码由于只是对spring的事务进行测试,所以异常没有特别处理,包括其他的代码,都是个人在私下编写,仅供朋友们参考!

测试设计:

1:业务接口:

package ioc;

public interface CategoryService
{
public void save(Parameter para) throws Exception;
}
2:业务实现

package ioc;

public class CategoryBiz implements CategoryService
{

private CategoryManager categoryManager = null;

public void save(Parameter para) throws Exception
{

//implements
//
categoryManager.save(c);
}

public CategoryManager getCategoryManager()
{
return categoryManager;
}

public void setCategoryManager(CategoryManager categoryManager)
{
this.categoryManager = categoryManager;
}

}
3:持久管理接口,持久实体 Category

package ioc;

public interface CategoryManager
{
public void save(Category category) throws Exception;
}
4:持久管理实现

package ioc;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class package ioc;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class CategoryDAO extends HibernateDaoSupport implements CategoryManager
{

public void save(Category category) throws Exception
{
try
{
this.getHibernateTemplate().save(category);
}
catch (Exception e)
{
throw e;
}
}

}
5:bean 管理工厂

这里暂时采用饿汉方式实现:朋友们也可以采用懒汉方式实现。

package ioc;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanFactory
{

private static ApplicationContext applicationContext = null;

private static BeanFactory self = null;
static
{
if (applicationContext == null)
{
try
{
applicationContext = new ClassPathXmlApplicationContext(
"ioc/applicationContext.xml");
}
catch (BeansException e)
{
e.printStackTrace();
}
}
}

synchronized public static BeanFactory getInstance()
{
if (self == null)
{
self = new BeanFactory();
}
return self;
}

public Object getBeanById(String beanId)
{
Object bean = null;
try
{
bean = applicationContext.getBean(beanId);
}
catch (BeansException e)
{
e.printStackTrace();
}
return bean;
}

}

6:标准context配置文件 applicationProxyContext.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="SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>ioc/hibernate.cfg.xml</value>
</property>
</bean>
<bean id="TransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory" />
</bean>

<!--逐个配置代理模式 事务和业务并行,支持事务嵌套 -->
<bean id="CategoryManager" class="ioc.CategoryDAO">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
<bean id="CategoryService" class="ioc.CategoryBiz">
<property name="categoryManager" ref="CategoryManager" />
</bean>

<bean id="CategoryServiceProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>ioc.CategoryService</value>
</list>
</property>
<property name="target">
<ref bean="CategoryService" />
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">
PROPAGATION_NESTED,-java.lang.Exception
</prop>
</props>
</property>
<property name="transactionManager">
<ref bean="TransactionManager" />
</property>
</bean>

</beans>
7:标准配置测试:

package ioc;

import java.util.Date;

public class ServiceProxyTest
{
public static void main(String[] s) throws Exception
{
try
{
BeanFactory beanFactory = BeanFactory.getInstance();
//
CategoryService categoryService = (CategoryService) beanFactory
.getBeanById("CategoryServiceProxy");
//implements
//
categoryService.save(form);
System.out.println("service proxy save ok!");
}
catch (Exception e)
{
e.printStackTrace();
}

}

}
8:自动代理配置模式: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="SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="ioc/hibernate.cfg.xml" />
</bean>
<bean id="TransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory" />

<!-- 注意:下边这个属性一定不要少,把嵌套事务的开关打开-->
<property name="nestedTransactionAllowed" value="true" />
</bean>
<!-- PROPAGATION_NESTED -->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="TransactionManager" />
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_NESTED</prop>
<prop key="del*">PROPAGATION_NESTED</prop>
<prop key="update*">PROPAGATION_NESTED</prop>
</props>
</property>
</bean>

<!-- 自动代理配置,事务和业务并行,支持嵌套事务 -->
<bean id="BeanNameAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>*Service</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>

<bean id="CategoryManager" class="ioc.CategoryDAO">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
<bean id="CategoryService" class="ioc.CategoryBiz">
<property name="categoryManager" ref="CategoryManager" />
</bean>

</beans>
9:自动代理 BeanNameAutoProxyCreator 配置模式测试 :

package ioc;

import java.util.Date;

public class CategoryServiceTest
{
public static void main(String[] s) throws Exception
{
try
{
BeanFactory beanFactory = BeanFactory.getInstance();
//
CategoryService categoryService = (CategoryService) beanFactory
.getBeanById(CategoryService.class.getSimpleName());
//implements
//
categoryService.save(form);
System.out.println("service save ok!");
}
catch (Exception e)
{
e.printStackTrace();
}

}

}
测试都很平稳的通过,里面的异常没有特别处理,这里强调的是在事务配置方面,最好把事务配置在业务上,这样业务始终和事务并行,不可能出现事务嵌套!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: