Spring 使用Hibernate事务管理:update等操作无效果问题

49 篇文章 0 订阅
16 篇文章 0 订阅

使用Spring事务管理

  • 需要使用getCurrentSession获取session
  • 在操作中不要显示的关闭session
  • 不需要进行编码式事务,使用声明式事务

实际问题:

  • 经常会遇到事务管理使用hibernate时,在调用update方法时,数据返回正确,而数据 库却没有更新
  • 调用save保存数据时,返回存储成功,数据库没有更新
  • 删除数据时删除成功,数据库依然没有更新等问题

原因:

  • applicationContext.xml(类似同名)配置文件中,针对hibernate的事务管理配置与service定义的方法名称不相符
  • 事物配置中定义了只读权限,因此修改失败
  • 事物配置未覆盖定义service
  • springmvc与hibernate的扫描位置冲突

详细解释:

  • 事物配置中定义了类似【<tx:method name=“update*” propagation=“REQUIRED” />】的属性,即意味着以update开头的service具备了操作权限,但是如果用户自己定义的update拼写错误如拼写为updata等是无法真正更新成功的。
  • <tx:method name=“change*” propagation=“REQUIRED” />定义了此属性,却命名service名称以其他方式开头如update这样依然是无法更新成功的。
  • <tx:method name=“update*” propagation=“REQUIRED” read-only=“true” />,属性中限制了只能读取的操作,因此依然无法更新成功name 是
    与事务属性关联的方法名。通配符()可以用来指定一批关联到相同的事务属性的方法。 如:'get’、‘handle*’、'on*Event’等等。

propagation 不 REQUIRED 事务传播行为
REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
isolation 不 DEFAULT 事务隔离级别
timeout 不 -1 事务超时的时间(以秒为单位)
read-only 不 false 事务是否只读?
rollback-for 不 将被触发进行回滚的 Exception(s);以逗号分开。 如:‘com.foo.MyBusinessException,ServletException’

no-rollback-for 不 不 被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException

实例:(详细列举了各类配置方式)

在spring配置文件中添加如下代码

 <!-- 在 IOC 容器中配置 Hibernate 的事务管理器 -->
   <bean id="transactionManager"
       class="org.springframework.orm.hibernate4.HibernateTransactionManager">
       <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
 
    <!-- 配置事务通知属性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 定义事务传播属性 -->
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="edit*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="new*" propagation="REQUIRED" />
            <tx:method name="set*" propagation="REQUIRED" />
            <tx:method name="remove*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="change*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" propagation="REQUIRED" />
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

此时的dao层只需要简单的 session().update(entity)就行了。

补充

上面的都是转载来的,这个是我自己写的:

public void delete(Collection persistentInstance) {
		log.debug("deleting Collection instance");
		try {
			sessionFactory.getCurrentSession().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

这个是我用hibernate tools 自动生成的DAO,执行了delete,但是没有任何反应,也没有报错,很是疑惑。
无意间观察到persistentInstance 而不是Instance,所以问题出在传入的对象必须是刚刚从数据库中findById 或者findByExample出来的新鲜对象(不能没有Id)哦!

作者:zafer
来源:CSDN
原文:https://blog.csdn.net/swazer_z/article/details/75552566

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值