在spring+hibernaet+mysql事务处理中遇到的一些坑

spring的事务处理本来就是依赖于底层的实现,比如hibernate及数据库本身。

所以,当使用mysql数据库时,首先要确定的是,所操作的对象表是innodb格式的。

1. read-only方法中进行更新或插入操作时,并不总报错

在service层的方法中定义了事务,并且在spring配置文件中定义了如下的传播方式:

<tx:attributes >
  <tx:method name="save*" propagation="REQUIRED" />
  <tx:method name="update*" propagation="REQUIRED" />
  <tx:method name="*" read-only= "true" />
 </tx:attributes>

假设有一个实体名称为User,则如果在在service的一个方法中想保存或更新它,而这个方法又忘记了以save或update开头,就会导致一些莫名其妙的事情发生,有时会报错(这可以理解),但有时又不会报错,动作却没有执行,反复观察,发现以下规律:

当更新user的操作时,即此时user的主键不为null时,调用Dao中的Hibernate的saveOrUpdate方法时,程序不报错,但修改动作未起作用;

当进行插入操作时,此时user的主键为Null(库中的主键采用自增),此时调用saveOrUpdate方法时,程序报错:Connection is read-only. Queries leading to data modification are not allowed.

2. 在事务方法中抛出异常,并不总回滚

一个事务方法中:

xxxDao.save(user);
.....
throw new Exception("要求回滚");

  

抛出异常后,期望事务能回滚,观察数据库,却发现改变已写进持久层了。

原因是这样的:Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚。Exception这个异常是checked异常,所以无法触发回滚事件,如果换成抛出RuntimeException异常,则程序运行就符合预期了。

3. 事务方法嵌套调用

在一个service中,用一个read-only方法调用非read-only方法,则发现整个调用都read-only了。

这是因为:service内部方法间调用,被调用方法设定的事务行为将会失效,事务行为由最外层方法设置的事务行为控制。

4. 事务回滚未提交,并不表示对底层数据库没有任何影响。

下面的代码:

xxxDao.save(user);  

Integer userId = user.getId();
.....
throw new RuntimeException("要求回滚");

事务会成功回滚,数据表中也未插入新的记录。但观察发现,userId的值也取到了,比如说userId=9800,如果再向数据库增加一条记录,则自增的id值会变成9801!

也就是说,虽然由于事务回滚没有向持久层插入记录,但数据表的自增字段的值已经被改变了。(这一块的机制细节没功夫研究了,有人了解的话,告诉我一下)

时间: 2024-10-09 21:28:15

在spring+hibernaet+mysql事务处理中遇到的一些坑的相关文章

RuntimeException和Exception事务处理中的区别

异常的分类: ① 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException. ② Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked). runtimeException就是运行时异常,它是java编译器事先不可预见的异常.

Ajax+SpringMVC+Spring+Mybatis+MySql+js用户注册实例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:这几天研究了下Ajax注册的方法,通过在注册时输入用户名或邮箱等,就可以判断这个用户是否存在,以免用户来注册,然后提交了,系统才提示该用户名或邮箱不可用.使用Ajax便可实现这一功能,看了网上的都是php的,想想索性来写一个SpringMVC+Spring+Mybatis的.文章内容用到了很多技术,包括javascript.jquery.json.e表达式等. 先来看看最终效果: 注册

springmvc学习总结(二) -- maven+springmvc+spring+mybatis+mysql详细搭建整合过程讲解

@[email protected] 写在最前 之前分享过下面这几篇: mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上)(附demo和搭建过程遇到的问题解决方法) mybatis学习笔记(六) -- maven+spring+mybatis从零开始搭建整合详细过程(下) springmvc学习笔记(一) -- 从零搭建,基础入门 这一篇,在这些练习的基础上,将它们整合在一起! 搭建步骤如下 一.新建maven项目,配置环境,测试是否配置成

Spring源码阅读:Spring声明式事务处理和编程式事务处理的设计与实现

之前的学习,了解了Spring事务管理的基础框架(查看).Spring在此基础上又提到了声明式事务管理和编程式事务管理.这里就来看看Spring是如何实现的. Spring声明式事务与EJB事务管理对比 Spring的声明式管理,类似于EJB的CMT,但又有不同.他们的不同之处有: 1)EJB的CMT是与JTA结合使用,而Spring框架的声明式事务管理可以在任何环境下工作.既可以使用全局事务管理,如JTA,也可以使用局部事务管理如JDBCJPA.Hibernate.JDO等. 2)可以在任何类

转载 深入浅出mysql事务处理和锁机制

1. 事务处理和并发性 1.1. 基础知识和相关概念 1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置的事务功能. 2 )使用 begin 开始事务,使用 commit 结束事务,中间可以使用 rollback 回滚事务. 3 )在默认情况下, InnoDB 表支持一致读. SQL 标准中定义了 4 个隔离级别: read uncommited , read commited , repeatable read , serializable . read uncomm

SpringMVC+Spring+Mybatis+Mysql项目搭建

眼下俺在搭建一个自己的个人站点玩玩.一边练习.一边把用到的技术总结一下,日后好复习. 站点框架大致例如以下图所看到的: 眼下仅仅用到了SpringMVC+Spring+Mybatis+Mysql.把它弄到了自己的server上来玩耍. 后台结构图: 眼下主要分为: view–controller层与前台交互,登陆拦截器 utils–工具类.一些经常使用的工具类. interceptor–拦截器.页面请求地址拦截和预防XSS漏洞拦截. impl–接口类,Service层-进行业务处理. excep

freemarker + spring mvc + spring + mybatis + mysql + maven项目搭建

今天说说搭建项目,使用freemarker + spring mvc + spring + mybatis + mysql + maven搭建web项目. 先假设您已经配置好eclipse的maven,创建好一个maven的web项目--Demo.我这里是jdk1.7,tomcat7. 修改pom.xml如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/

SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置

转载:http://blog.csdn.net/xiadi934/article/details/50786293 项目环境: 在SpringMVC +Spring + MyBatis + MySQL.Redis部署在Linux虚拟机. 1.整体思路 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅) 使用Spring管理Redis连接池 模仿EhcacheCache,实现RedisCache 2.pom.xml中加入Maven依赖 1 <!-- spring-re

spring cloud:Edgware.RELEASE版本hystrix超时新坑

升级到Edgware.RELEASE发现,zuul中不管如何设置hystrix的超时时间均不起作用,仍然是默认的1000ms.  降回低版本后正常,但是低版本的fallback方法中,又拿不到详细异常信息,最终暂时在Edgware.RELEASE中,将hystrix的超时关掉,参考以下配置: ribbon: ReadTimeout: 5000 ConnectTimeout: 5000 MaxAutoRetries: 0 MaxAutoRetriesNextServer: 1 hystrix: c