`
terry_yip
  • 浏览: 38762 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

spring事务管理的控制问题

阅读更多
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
  <property name="sessionFactory"><ref local="sessionFactory"/></property>  
 </bean> 
 
  <bean id="userDao" class="hibernate.dao.Dao">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
  </bean>
  
  <bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
     <property name="transactionManager"><ref local="transactionManager"/></property> 
     <property name="target"><ref local="userDao"/></property>
     <property name="transactionAttributes">
       <props>
                  <prop key="insert*">PROPAGATION_REQUIRED</prop>
                  <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
		  <prop key="query">PROPAGATION_REQUIRED,readOnly</prop>
		  <prop key="update">PROPAGATION_REQUIRED</prop>
		  <prop key="execute">PROPAGATION_REQUIRED</prop>  
       </props>
     </property>
  </bean>


用spring跟hibernate结合的方式,如果我在插入一条数据时,想往备份数据库的备份表也插入一条同样的记录
例如

public void update()
{  
//从上面的配置文件,得到两个userDaoProxy对象, 
  formalDaoProxy.update(bean);
  backupDaoProxy.update(bean);
}


这样的话,由于正式表与备份表要保持数据一致性,所以,两个update其中一个失败, 另一个都要rollback , 但是这两个Dao, 分别由两个独立事务来自动管理的, commit或rollback都不能干预, 请问怎样可以用代码来控制其rollback?我找了很久都找不到.请教一下大家, 谢谢.
分享到:
评论
22 楼 zozofo 2007-06-21  
问题解决了,还是在本网站找到的解决办法。提供URL:http://www.iteye.com/topic/10296(见第6个问题)
21 楼 zozofo 2007-06-20  
id:checkuser更改为:checkuserservice
20 楼 zozofo 2007-06-20  
和kele8boy碰到的情况一样,及时target映射的是service层,service包含的两个不同DAO的方法也不能被事务管理。比如update1()和update2()
$update1()//正确
$update2()//异常
update1()还是被提交、update2()提交失败。两者并没有管理在同一个事务中。
配置文件如下:

<beans>
<bean id="adminDataSource"
class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"
destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/joe" />
<property name="username" value="" />
<property name="password" value="" />
</bean>

<bean id="accountDataSource"
class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/test" />
<property name="username" value="root" />
<property name="password" value="123" />
</bean>

<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="adminDataSource" />
<property name="mappingResources">
<list>
<value>backup/Admin.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>org.hibernate.dialect.MySQLDialect</value>
</property>
</bean>

<bean id="mySessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="accountDataSource" />
<property name="mappingResources">
<list>
<value>backup/Account.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>org.hibernate.dialect.MySQLDialect</value>
</property>
</bean>

<bean id="admindao" class="dao.AdminDAO">
<property name="sessionfactory" ref="mySessionFactory" />
</bean>

<bean id="accountdao" class="dao.AccountDAO">
<property name="sessionfactory" ref="mySessionFactory" />
</bean>



<bean id="checkuser" class="service.local.CheckUser">
<property name="admindao" ref="admindao" />
<property name="accountdao" ref="accountdao" />
</bean>

<bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory2"/>
</bean>


<bean id="myProductService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="myTxManager"/>
</property>
<property name="target" ref="checkuserservice"/>


<property name="transactionAttributes">
<props>
<prop key="update*">PROPAGATION_REQUIRED</prop>

</props>
</property>
</bean>



</beans>
19 楼 zzcclp 2007-03-09  
如下是我的代码:
<bean id="userManagerTarget" class="zzc.stu.service.impl.UserManagerImpl">
<property name="dao">
<ref local="userDAO"/>
</property>
</bean>
<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="myTransactionManager"/>
</property>
<property name="target">
<ref local="userManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
18 楼 zzcclp 2007-03-09  
<property name="target"><ref local="userDao"/></property>
你的target指向的应该是service层的类,而不是直接的dao
17 楼 我想我是海 2007-03-06  
terry_yip 写道
因为这种结合方式本身就带"自动"的事务管理机制了.

所谓的自动是不需要你写代码显式进行事务管理。但前提还是还你去手动配置,让Spring知道你哪里需要事务参与。没有说你用Spring配置了一个DAO,那么这个DAO就有了神奇的自动事务管理功能。
最简单的做法就是把你那两个DAO的事务配置去掉(还原从纯粹的Bean非代理Bean),再在Service加上事务代理即可。
这样完整配置下来,从Service开始到结束都是一个事务,两个DAO的操作属于同一个事务中的操作。简单有效,何乐而不为?干嘛要每个DAO配上事务,而且为每个DAO配事务极度不可取。
16 楼 ahuaxuan 2007-03-06  
TransactionProxyFactoryBean的target应该是业务对象,你需要做的就是把业务对象付给TransactionProxyFactoryBean的target,然后其他一样配置,这样,你的service就能享受声明式事务处理了,或者通过自动代理来简化声明式事务的配置也是可以的
15 楼 terry_yip 2007-03-06  
有个问题我不明白, 很多人都说我不应在DAO层做事务管理, 我也认同这个说法,但是,我觉得我是被spring和hibernate结合的方式逼着我这样做的, 因为这种结合方式本身就带"自动"的事务管理机制了. 不知是否我的那个配置文件的bean的名字带有DAO误导了大家,还是我真的有什么别的方法不知道,难道我应该把那个spring默认的事务管废掉,自己写commit, rollback吗? 如果是这样的话, 那我这部分直接用hibernate做算了, 为何还要用spring+hibernate方法呢??请大家指点一下,或说说你们在项目中是怎么处理这个问题的.

14 楼 ahuaxuan 2007-03-06  
是这样的,但是很少有人在dao上做事务控制的,应该是CompleteService类才对,理论上讲我们不应该在持久层做事务控制,应该在业务层(极少数情况除外),楼主对事务的概念非常模糊,建议去系统的看看相关的书籍
13 楼 terry_yip 2007-03-06  
Godlikeme 写道

如果service层有事务控制,整个事务由最外层service层事务控制,propagation required.



你的意思, 是不是这样, 例如 我再写多一个CompleteDao类, 然后加入类似方法

public void updateBoth()
{
   xxDao.update(bean);
   xxBackupDao.update(bean)
}



然后, 在配置文件中,

  <bean id="CompleteDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
     <property name="transactionManager">
          <ref local="transactionManager"/>
     </property>   
     <property name="target"><ref local="CompleteDao"/></property> 
     <property name="transactionAttributes"> 
       <props> 
           <prop key="updateBoth">PROPAGATION_REQUIRED</prop> 
       </props> 
     </property> 
  </bean> 


是不是这样?

12 楼 ahuaxuan 2007-03-06  
terry_yip 写道
ahuaxuan 写道
terry_yip 写道
OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?


这里面根本就没有什么问题,你只要给service加上事务代理就ok了,不会有什么问题


如果我用JDBC的方法来连,  我可以connnection.commit()或connnection.rollback();

如果用hibernate的方式来连接,

Transaction tx = session.beginTransaction();
tx.commit();或tx.rollback();

但用我以上的方式来连接数据库,是怎么rollback()或commit()呢? 其实我问题的核心就是在这个点上.


如果是声明式事务处理,你只要抛出异常就自动rollback了,如果不抛异常,方法自动通过,那就commit了,不需要你手动的rollback何commit,这个就是声明式事务处理的优点之一
11 楼 Godlikeme 2007-03-06  
terry_yip 写道
Godlikeme 写道
有没有service层?
Service层有没有设置transaction?
个人认为,应该在service层做这种事务控制。



有逻辑事务层, 我上面的public void update()方法,就是在相当于你说的service层做的,但问题是, 我再开一个transaction,怎样能控制当其中一个DaoProxy.update(bean)失败了,另一个update的操作rollback?



如果service层有事务控制,整个事务由最外层service层事务控制,propagation required.
10 楼 terry_yip 2007-03-06  
ahuaxuan 写道
terry_yip 写道
OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?


这里面根本就没有什么问题,你只要给service加上事务代理就ok了,不会有什么问题


如果我用JDBC的方法来连,  我可以connnection.commit()或connnection.rollback();

如果用hibernate的方式来连接,

Transaction tx = session.beginTransaction();
tx.commit();或tx.rollback();

但用我以上的方式来连接数据库,是怎么rollback()或commit()呢? 其实我问题的核心就是在这个点上.

9 楼 ahuaxuan 2007-03-06  
terry_yip 写道
OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?


这里面根本就没有什么问题,你只要给service加上事务代理就ok了,不会有什么问题
8 楼 terry_yip 2007-03-06  
OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?

7 楼 ahuaxuan 2007-03-06  
引用
备份数据库的备份表也插入一条同样的记录

备份数据库? 有两个数据库?
如果主表何备份表在一个schema里,只要把最外面的update方法的事务传播途径设置称required就可以了
6 楼 kof99th 2007-03-06  
事务应该配置在service上,而不是dao
5 楼 kof99th 2007-03-06  
事务应该配置在service上,而不是dao
4 楼 terry_yip 2007-03-06  
我最主要的问题是,

public void update()   
{       
  formalDaoProxy.update(bean);  //update1 
  backupDaoProxy.update(bean);   //update2
}


最主要的问题是, update1一执行成功,马上被自动commit了,如果接下来update2失败了,那主数据库和备份数据库中的数据就不一致了. 所以我想把两个update,归为一个事务当中,两个update都成功,才两个一起commit. 但是又不想把所有相关代码都重写,所以问一下有没有解决的办法.


3 楼 terry_yip 2007-03-06  
Godlikeme 写道
有没有service层?
Service层有没有设置transaction?
个人认为,应该在service层做这种事务控制。



有逻辑事务层, 我上面的public void update()方法,就是在相当于你说的service层做的,但问题是, 我再开一个transaction,怎样能控制当其中一个DaoProxy.update(bean)失败了,另一个update的操作rollback?

相关推荐

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    Spring事务管理开发必备jar包

    本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...

    spring事务控制

    spring事务控制jar包,请网上自寻下载

    Spring事务管理的jar包

    本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...

    Spring事务管理失效原因汇总

    标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...

    spring 事务管理的理解

    Spring 框架是Java开发中...理解并熟练掌握Spring事务管理,对于提升应用程序的稳定性和可靠性至关重要。在实际开发中,结合声明式事务管理、事务传播行为、隔离级别和回滚规则,可以有效地确保数据的完整性和一致性。

    spring事务管理5种方法

    本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...

    spring事务管理

    ### Spring事务管理详解 #### 一、Spring事务管理概述 Spring框架提供了强大的事务管理功能,使得开发者能够更方便地管理应用程序中的事务。Spring事务管理主要包括两种类型:编程式事务管理和声明式事务管理。 -...

    实验 spring 声明事务

    Spring 提供了声明式事务管理,允许开发者在不编写事务管理代码的情况下实现事务控制,极大地简化了事务处理。 实验环境主要包括 Eclipse 或 MyEclipse 开发工具,以及 Spring 4.0 及以上版本,JDK 1.7 及以上版本...

    Spring的事务管理小案例

    在本文中,我们将深入探讨Spring框架中的事务管理。Spring是一个广泛应用的Java企业级应用开发框架,它提供...如果你想要深入了解,可以参考提供的博客链接或其他相关资料,进一步学习Spring事务管理的细节和最佳实践。

    spring 自定义事务管理器,编程式事务,声明式事务@Transactional使用

    在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本教程将深入探讨如何在Spring中实现自定义事务管理器...这将加深你对Spring事务管理的理解,帮助你在实际项目中更加熟练地运用这些技术。

    spring事务操作试验

    首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务管理分为两种模式:声明式事务管理和编程式事务管理。声明式事务管理通过配置元数据(如XML或...

    spring事务与数据库操作

    ### Spring事务与数据库操作 ...综上所述,Spring框架不仅提供了强大的事务管理功能,而且还支持灵活的AOP机制,使得开发者能够在保持业务逻辑清晰的同时,轻松实现诸如事务控制、权限验证等跨切关注点。

    全面分析_Spring_的编程式事务管理及声明式事务管理

    你可以创建一个简单的 Spring 应用,配置事务管理器,并在业务层使用 @Transactional 注解或 TransactionTemplate 进行事务控制,以加深理解和应用。 总的来说,Spring 的事务管理机制提供了强大而灵活的支持,无论...

    spring-tx事务管理实例

    Spring事务管理是企业级Java应用中不可或缺的一部分,它确保了数据的一致性和完整性,尤其是在多线程和分布式环境中。本实例将深入探讨Spring事务管理的实现与应用。 首先,Spring事务管理分为编程式事务管理和声明...

    spring_事务管理(实例代码)

    Spring事务管理就是围绕这些特性来确保数据的一致性。 四、事务的传播行为 在Spring中,我们可以配置事务的传播行为,比如REQUIRED(默认,如果当前存在事务,则加入当前事务,否则新建一个事务)、PROPAGATION_...

    Spring 框架的事务管理及应用

    ### Spring框架的事务管理及应用 #### Spring框架概述 Spring框架是一个开源项目,最早出现在2003年2月,其起源可以追溯到Rod Johnson在2002年末出版的书籍《Expert One-on-One J2EE Design and Development》中的...

    Spring事务管理A方法内部调用B方法的回滚问题测试代码

    在Spring框架中,事务管理是核心特性之一,用于确保数据操作的一致性和完整性。当一个方法(A方法)内部调用另一个方法(B方法)时,可能会遇到事务控制...这个示例代码对于理解和调试Spring事务管理的问题非常有帮助。

    Spring事务管理4种方式

    本文将详细介绍Spring事务管理的四种方式:编程式事务管理、声明式事务管理、PlatformTransactionManager接口以及TransactionTemplate。 1. **编程式事务管理**:这是一种手动控制事务的方式,通过在代码中调用`...

Global site tag (gtag.js) - Google Analytics