论坛首页 Java企业应用论坛

『提问』『提问』spring如何处理多个dao

浏览 7417 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-11-27  
DAO
软件环境:
软件环境:
struts+spring+hibernate
配置文件:
ApplicationContext-service.xml如下片断:

<bean id="txProxyTemplate" lazy-init="true"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
&lt;property name="transactionManager"&gt;
&lt;ref bean="transactionManager"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
</bean>
<bean id="menuManagerTarget" parent="xtProxyTemplate">
&lt;property name="target"&gt;
<bean class="com.sales.service.impl.MenuManagerImpl">
&lt;property name="menuDAO"&gt;
&lt;ref bean="menuDAO"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;property name="permissionDAO"&gt;
&lt;ref bean="permissionDAO"&gt;&lt;/ref&gt;
&lt;/property&gt;
</bean>
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
                                &lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
</bean>
错误提示信息:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'xtProxyTemplate' is defined: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,menuDAO,departDAO,roleDAO,permissionDAO,userDAO,menuManager,departManager,roleManager,permissionManager,userManager,txProxyTemplate,menuManagerTarget]; Root of BeanFactory hierarchy

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:291)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:554)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:579)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:554)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.isBeanDefinitionTypeMatch(DefaultListableBeanFactory.java:124)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinitionNames(DefaultListableBeanFactory.java:106)

at org.springframework.context.support.AbstractApplicationContext.getBeanDefinitionNames(AbstractApplicationContext.java:464)

at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:307)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:266)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:80)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:65)

at test.sales.service.impl._TestMenuManagerImpl.setUp(_TestMenuManagerImpl.java:17)

...(Click for full stack trace)...
你的分析:
因为业务的需要,几个数据表之间并没有关系,但是要求在业务处理上考虑事务的问题,但是spring怎样管理多个dao的事务呢?
配置文件:
ApplicationContext-service.xml如下片断:

<bean id="txProxyTemplate" lazy-init="true"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
&lt;property name="transactionManager"&gt;
&lt;ref bean="transactionManager"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
</bean>
<bean id="menuManagerTarget" parent="xtProxyTemplate">
&lt;property name="target"&gt;
<bean class="com.sales.service.impl.MenuManagerImpl">
&lt;property name="menuDAO"&gt;
&lt;ref bean="menuDAO"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;property name="permissionDAO"&gt;
&lt;ref bean="permissionDAO"&gt;&lt;/ref&gt;
&lt;/property&gt;
</bean>
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
                                &lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
</bean>
错误提示信息:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'xtProxyTemplate' is defined: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [dataSource,sessionFactory,transactionManager,menuDAO,departDAO,roleDAO,permissionDAO,userDAO,menuManager,departManager,roleManager,permissionManager,userManager,txProxyTemplate,menuManagerTarget]; Root of BeanFactory hierarchy

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:291)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:554)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:579)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:554)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.isBeanDefinitionTypeMatch(DefaultListableBeanFactory.java:124)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinitionNames(DefaultListableBeanFactory.java:106)

at org.springframework.context.support.AbstractApplicationContext.getBeanDefinitionNames(AbstractApplicationContext.java:464)

at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:307)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:266)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:80)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:65)

at test.sales.service.impl._TestMenuManagerImpl.setUp(_TestMenuManagerImpl.java:17)

...(Click for full stack trace)...
你的分析:
因为业务的需要,几个数据表之间并没有关系,但是要求在业务处理上考虑事务的问题,但是spring怎样管理多个dao的事务呢?
   发表时间:2004-11-29  
原来是parent="txTargetManager"写错了,但是程序运行后,如果一个dao操作失败,另一个确直接插入了,不能回滚,不知道什么原因。spring 该不会是不能在service端管理事务吧?
0 请登录后投票
   发表时间:2004-11-29  
wangdongzjk 写道

因为业务的需要,几个数据表之间并没有关系,但是要求在业务处理上考虑事务的问题,但是spring怎样管理多个dao的事务呢?


你这样的声明只是对DAO做的,也就是说如果你单个DAO中出现异常等,事务会自动回滚的. 如果要达到对多个DAO的事务管理,你应该在service中调用多个dao,然后把事务声明在service层,这样如果一个DAO中出现问题,就会回滚整个service中所做的更改.

我觉得DAO中没有必要声明事务,完全可以放在service层.
0 请登录后投票
   发表时间:2004-11-29  
新的声明文件:
<bean id="myMenuServiceTarget" class="com.sales.service.impl.MenuManagerImpl">
          <property name="menuDAO">
            <ref bean="menuDAO"></ref>
          </property>
          <property name="permissionDAO">
            <ref bean="permissionDAO"></ref>
          </property>
        </bean>
        <bean id="myMenuService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          <property name="transactionManager">
            <ref bean="transactionManager"/>
          </property>
          <property name="target">
            <ref bean="myMenuServiceTarget"/>
          </property>
          <property name="transactionAttributes">
            <props>
              <prop key="save*">PROPAGATION_REQUIRED</prop>
              <prop key="update*">PROPAGATION_REQUIRED</prop>
              <prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop>
            </props>
          </property>
        </bean>


我做了如下修改:
       更改数据库menu表的设置,把menuname(非主键)设成unique;
这样做是不会插入了,但是系统的异常捕获不到:

Hibernate: insert into permission (permissionid, permissionparentid, permissionname, id); values (?, ?, ?, ?);

Hibernate: insert into menu (parentid, menuname, menulink, id); values (?, ?, ?, ?);

2004-11-29 22:12:33,218 WARN [net.sf.hibernate.util.JDBCExceptionReporter] - <SQL Error: 1062, SQLState: 23000>

2004-11-29 22:12:33,218 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] - <Duplicate key or integrity constraint violation,  message from server: "Duplicate entry 'menu7' for key 2">

2004-11-29 22:12:33,234 WARN [net.sf.hibernate.util.JDBCExceptionReporter] - <SQL Error: 1062, SQLState: 23000>

2004-11-29 22:12:33,234 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] - <Duplicate key or integrity constraint violation,  message from server: "Duplicate entry 'menu7' for key 2">

2004-11-29 22:12:33,234 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] - <Could not execute JDBC batch update>

java.sql.BatchUpdateException: Duplicate key or integrity constraint violation,  message from server: "Duplicate entry 'menu7' for key 2"

	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1461);

	at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294);

	at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54);

	at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:126);

	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2421);

	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2371);

	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240);

	at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61);

	at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:460);

	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:373);

	at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:241);

	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66);

	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:138);

	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:152);

	at $Proxy0.saveMenu(Unknown Source);

	at test.sales.service.impl._TestMenuManagerImpl.testSaveMenu(_TestMenuManagerImpl.java:35);

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method);

	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39);

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25);

	at java.lang.reflect.Method.invoke(Method.java:324);

	at junit.framework.TestCase.runTest(TestCase.java:154);

	at junit.framework.TestCase.runBare(TestCase.java:127);

	at junit.framework.TestResult$1.protect(TestResult.java:106);

	at junit.framework.TestResult.runProtected(TestResult.java:124);

	at junit.framework.TestResult.run(TestResult.java:109);

	at junit.framework.TestCase.run(TestCase.java:118);

	at junit.framework.TestSuite.runTest(TestSuite.java:208);

	at junit.framework.TestSuite.run(TestSuite.java:203);

	at com.borland.jbuilder.unittest.JBTestRunner.a(Unknown Source);

	at com.borland.jbuilder.unittest.JBTestRunner.initiateTest(Unknown Source);

	at com.borland.jbuilder.unittest.JBTestRunner.main(Unknown Source);

2004-11-29 22:12:33,250 ERROR [net.sf.hibernate.impl.SessionImpl] - <Could not synchronize database state with session>

net.sf.hibernate.JDBCException: Could not execute JDBC batch update

	at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:133);

	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2421);

	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2371);

	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240);

	at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61);

	at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:460);

	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:373);

	at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:241);

	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66);

	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:138);

	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:152);

	at $Proxy0.saveMenu(Unknown Source);

	at test.sales.service.impl._TestMenuManagerImpl.testSaveMenu(_TestMenuManagerImpl.java:35);

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method);

	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39);

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25);

	at java.lang.reflect.Method.invoke(Method.java:324);

	at junit.framework.TestCase.runTest(TestCase.java:154);

	at junit.framework.TestCase.runBare(TestCase.java:127);

	at junit.framework.TestResult$1.protect(TestResult.java:106);

	at junit.framework.TestResult.runProtected(TestResult.java:124);

	at junit.framework.TestResult.run(TestResult.java:109);

	at junit.framework.TestCase.run(TestCase.java:118);

	at junit.framework.TestSuite.runTest(TestSuite.java:208);

	at junit.framework.TestSuite.run(TestSuite.java:203);

	at com.borland.jbuilder.unittest.JBTestRunner.a(Unknown Source);

	at com.borland.jbuilder.unittest.JBTestRunner.initiateTest(Unknown Source);

	at com.borland.jbuilder.unittest.JBTestRunner.main(Unknown Source);

Caused by: java.sql.BatchUpdateException: Duplicate key or integrity constraint violation,  message from server: "Duplicate entry 'menu7' for key 2"

	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1461);

	at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294);

	at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54);

	at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:126);

	... 27 more

2004-11-29 22:12:33,265 INFO [org.springframework.jdbc.support.SQLStateSQLExceptionTranslator] - <Translating SQLException with SQLState '23000' and errorCode '1062' and message [Duplicate key or integrity constraint violation,  message from server: "Duplicate entry 'menu7' for key 2"]; SQL was [] for task [HibernateTemplate]>



不知道是否是真正的事务,我觉得如果真的是spring管理了事务的话,不应该出现这些异常,但是我用hibernate在一个session中直接处理两个对应不同表的对象的save工作,虽然回滚但是也是同样的不能捕获异常,不知何解?
0 请登录后投票
   发表时间:2004-12-01  
主键的问题。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics