Spring @Transaction配置演示样例及发生不回滚原因深度剖析
背景
近期在公司做的一个项目,用的是SpringMVC框架,数据库用的是MySql,刚開始并没有增加事务,后因业务须要必须事务处理。
问题的产生和解决
使用事务,直接问百度,我选择的是注解的方式。
在配置文件里配置事务管理器和驱动:
<tx:annotation-driven transaction-manager="transactionManager"/> <bean
id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
然后直接在service层加注解
package com.my.service.impl; import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import com.my.constants.ServiceException;
import com.my.dao.TestDao;
import com.my.service.TestService; @Service
public class TestServiceImpl implements TestService{ @Autowired
private TestDao testDao; @Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { ServiceException.class })
public int insertUser(String userName) throws ServiceException {
int id = 0;
try {
id = testDao.insertUser(userName);
} catch (SQLException e) {
throw new ServiceException();
}
return id;
}
}
自然地,rollback的异常要和service抛出的异常一样才会回滚。
然后自觉得代码肯定没有问题。但是多次debug后到数据库取看都没有回滚,于是就直接在代码中增加错误代码int i = 5/0。并把exception的捕获改动一下
package com.my.service.impl; import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import com.my.constants.ServiceException;
import com.my.dao.TestDao;
import com.my.service.TestService; @Service
public class TestServiceImpl implements TestService{ @Autowired
private TestDao testDao; @Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { ServiceException.class })
public int insertUser(String userName) throws ServiceException {
int id = 0;
try {
id = testDao.insertUser(userName);
int i = 5/0;
} catch (Exception e) {
throw new ServiceException();
}
return id;
} }
用上面的代码多次调试。始终没有回滚。
然后自然想到,可能Dao层有问题。然后去看Dao层代码,似乎真的有问题:
package com.my.dao.impl; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository; import com.my.dao.TestDao; @Repository
public class TestDaoImpl implements TestDao { @Autowired
private JdbcTemplate jdbcTemplate; @Override
public int insertUser(final String userName) throws SQLException {
final String sql = "INSERT INTO USER(NAME) VALUES(?);";
KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = jdbcTem-plate.getDataSource().getConnection().prepareStatement(sql);
ps.setString(1, userName); return ps;
}
}, keyHolder); return keyHolder.getKey().intValue();
}
}
错误可能就在代码黄色块。
于是debug进去,看到Connectioncon中的autoCommit属性是false的,显然是被service层的事务管理到的,而jdbcTemplate.getDataSource().getConnection()是到链接池又一次获取的连接。这个连接显然没有被事务管理。它的autoCommit属性显然是true,所以这使得service层事务没有回滚。改起来非常easy,直接把代码中的黄色块改成PreparedStatement
ps = con.prepareStatement(sql);就能够了。
总结
遇到Springmvc事务不能回滚。解决的步骤:
1. 检查配置文件中面有没有增加事务管理配置和驱动;
2. 检查数据库是否支持事务(比如MySql4.0 支持事务,Engine:InnoDB);
3. 检查代码块是否抛出异常,且事务的rollback的异常是抛出异常或者是抛出异常的父类。
4. 检查事务覆盖的代码块中的全部Connection是否都被这个事务覆盖(debug检查全部connection的autoCommit属性是不是被事务改成了false)。
Spring @Transaction配置演示样例及发生不回滚原因深度剖析的更多相关文章
- Nginx 简单的负载均衡配置演示样例
近期在做开放查询应用的时候,因为数据两天特别多,两千多万条呢,用户訪问需求也比較大,所以就用nginx做了 负载均衡,以下是改动之后的相关内容. http://www.cnblogs.com/xiao ...
- AOP经典2种配置演示样例
第一种: 使用aop指定切面aspect. <bean id="LogAdvice" class="com.thinkmore.framework.monitor. ...
- EEPlat vs saleforce 配置 Knowledge Article 演示样例
==================================================================================================== ...
- JBoss 系列一 O O:Maven jBPM 6 集成演示样例
概述 jBPM 6 中底层架构基于 Maven,所以我们能够非常easy的进行 Maven jBPM 6 集成演示样例,本文分三个部分: 基本原理介绍 Maven jBPM 6 集成 jBPM 6 中 ...
- Cocos2d-x 3.2Lua演示样例UserDefaultTest(用户默认配置)
Cocos2d-x 3.2演示样例UserDefaultTest(用户默认配置) 本篇博客介绍Cocos2d-x 3.2演示样例中的UserDefaulstTest,我们在开发中可能须要用到一些默认配 ...
- Tuxedo安装、配置、以及演示样例程序 (学习网址)
Tuxedo安装.配置.以及演示样例程序 (学习网址): 1.http://liu9403.iteye.com/blog/1415684 2.http://www.cnblogs.com/fnng/a ...
- SNF快速开发平台MVC-各种级联绑定方式,演示样例程序(包含表单和表格控件)
做了这么多项目,经常会使用到级联.联动的情况. 如:省.市.县.区.一级分类.二级分类.三级分类.仓库.货位. 方式:有表单需要做级联的,还是表格行上需要做级联操作的. 实现:实现方法也有很多种方式. ...
- Eureka 的 Application Service client的注冊以及执行演示样例
Eureka 服务器架起来了(关于架设步骤參考博客<Linux 下 Eureka 服务器的部署>),如今怎样把我们要负载均衡的服务器(也就是从 Application Cl ...
- JDBC连接MySQL数据库及演示样例
JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...
随机推荐
- Codeforces 801C Voltage Keepsake(二分枚举+浮点(模板))
题目链接:http://codeforces.com/contest/801/problem/C 题目大意:给你一些电器以及他们的功率,还有一个功率一定的充电器可以给这些电器中的任意一个充电,并且不计 ...
- ROSCon 2017通知 Announcing ROSCon 2017: September 21st and 22nd in Vancouver
ROSCon 2017通知:9月21日和22日在温哥华 我们很高兴地宣布,2017年ROSCon将在举行9月21-22日,2017年温哥华会议中心在加拿大温哥华.2017年IROS将在同一地点9月24 ...
- COLLATE CHINESE_PRC_CI_AS_WS 的含义
排序规则:COLLATE CHINESE_PRC_CI_AS_WS 的含义 在创建数据表时,常会用到这个. 含义当中,CHINESE_prc_ 是代表中国大陆.如果是台湾,则如:Chinese_TAI ...
- 日志、字段备注查询、自增ID联系设置、常用存储过程
-----获取数据字典SQL(表字段说明)SELECT [Table Name] = OBJECT_NAME(c.object_id), [Column Name] = c.name, ...
- nginx + tomcat 集群记录
昨天晚写的时候已经下班了.时间紧迫.写的略简! 昨天说过.接到部署的任务之后.首先想到的是apache httpserver 毕竟pache.我们接触的比较多!然而部署之后遇到了很多问题.比如apac ...
- SqlServer性能优化 Sql语句优化(十四)
一:在较小的结果集上上操作 1.仅返回需要的列 2.分页获取数据 EF实现分页: public object getcp(int skiprows,int currentpagerows) { HRU ...
- Struts DynaActionForm example
The Struts DynaActionForm class is an interesting feature to let you create a form bean dynamically ...
- nginx+keepalived高可用服务器宕机解决方案
http://blog.51cto.com/gdutcxh/2109841 https://blog.csdn.net/winsonyuan/article/details/52784988
- mysql千万级表关联优化(2)
概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上. 这个 ...
- Python全栈开发之18、cookies、session和ajax等相关知识
一.cookies 本质为在浏览器端保存的键值对,由服务端写在浏览器端,以后每次请求的时候,浏览器都携带着cookie来访问,cookies的使用之处非常多,比如用户验证,登陆界面,右侧菜单隐藏,控制 ...