Springsql 事务回滚在什么情况下,会进行sql回滚

博客访问: 555936
博文数量: 184
博客积分: 1992
博客等级: 上尉
技术积分: 1765
注册时间:
重庆乐潮信息技术有限公司
http://www.letide.cn
分类: Java 16:54:07
试验方法:
&&&&&&&& 写一个单元测试,调用一个service层方法(发生对数据库进行写操作的方法--insert、update、delete)即可.
试验过程:
&&&&&&&& 定义一个service方法如下:
&&&&&&&&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming){
&&&&&&&&&&&&&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&&&&&&&&&&&&&return&s;
&& & & &&}
&&&&&&&& 定义二个异常(先默认配置TestException为Spring事务回滚异常):
&&&&&&&&&&& publicclass&MyTestException&extends&Exception
&&&&&&&&&&& publicclass&TestException&extends&Exception
&&&&&&&&&注意看下:每次这个方法的不同处(抛出的异常不同)。
public&SMSTiming&createSMSTiming(SMSTiming smsTiming){
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&int&i = 4/0;&//人为产生异常(实际这里抛出了ArithmeticException运行异常)
&&&&&&&return&s;
测试1结果:会事务回滚----数据库中未插入新数据。
&&&&&&&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming)&throws&Exception{//受检异常(非运行异常)必须抛出
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&try{
&&&&&&&&&&&int&i = 4/0;&//人为产生异常
&&&&&&&}catch(Exception e){
&&&&&&&&&&&thrownew&Exception&("");//抛出Exception异常
&&&&&&&return&s;
测试2结果:不会事务回滚----数据库中插入新数据。
&&&&&&&& &&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming)&throws&RuntimeException{//运行异常(非受检异常)可以不抛出
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&try{
&&&&&&&&&&&int&i = 4/0;&//人为产生异常
&&&&&&&}catch(Exception e){
&&&&&&&&&&&thrownewRuntimeException("");//抛出RuntimeException异常
&&&&&&&return&s;
测试3结果:会事务回滚----数据库中未插入新数据
&&&&&&&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming)&throws&TestException{//受检异常(非运行异常)必须抛出
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&try{
&&&&&&&&&&&int&i = 4/0;&//人为产生异常
&&&&&&&}catch(Exception e){
&&&&&&&&&&&thrownewTestException("");//抛出TestException异常
&&&&&&&return&s;
测试4结果:会事务回滚----数据库中未插入新数据。
&&&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming)&throws&MyTestException{//受检异常(非运行异常)必须抛出
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&try{
&&&&&&&&&&&int&i = 4/0;&//人为产生异常
&&&&&&&}catch(Exception e){
&&&&&&&&&&&thrownewMyTestException("");//抛出MyTestException异常
&&&&&&&return&s;
&测试5结果:不会事务回滚----数据库中插入新数据。
&&&&public&SMSTiming&createSMSTiming(SMSTiming smsTiming)&throws&MyTestException{//受检异常(非运行异常)必须抛出&(注意:此时spring指定配置此异常回滚)
&&&&&&&SMSTiming s=&this.getSmsTimingDAO().createSMSTiming(smsTiming);
&&&&&&&try{
&&&&&&&&&&&int&i = 4/0;&//人为产生异常
&&&&&&&}catch(Exception e){
&&&&&&&&&&&thrownewMyTestException("");//抛出MyTestException异常
&&&&&&&return&s;
&测试6结果:会事务回滚----数据库中未插入新数据。
试验总结:
测试1、测试3、测试4、测试6会进行事务回滚;测试2、测试5不会进行事务回滚。
为什么会这样?因为是异常的类型(受检异常、运行时异常)不同或使用了Spring的rollback-for配置。
测试1和测试3是因为抛出了运行时异常,会事务回滚。
测试4和测试5、测试6分别抛出受检异常TestException、MyTestException,那为什么测试4和测试6会事务回滚呢?
因为是我们在Spring事务配置中指定了此异常(指定rollback-for)。
Spring框架的事务基础架构代码将默认地&只&在抛出运行时和unchecked exceptions时才标识事务回滚。 也就是说,当抛出一个&RuntimeException或其子类例的实例时。(Errors&也一样 - 默认地 - 标识事务回滚。)从事务方法中抛出的Checked exceptions将&不&被标识进行事务回滚
阅读(4484) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
请登录后评论。17:13 提问
spring @Transactional 事务不能回滚
在spring的配置文件里配置如下:
&!-- enable the configuration of transactional behavior based on annotations --&
&tx:annotation-driven transaction-manager="txManager"/&
&!-- a PlatformTransactionManager is still required --&
&bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&
&!-- (this dependency is defined somewhere else) --&
&property name="dataSource" ref="dataSource"/&
测试代码如下:
@Transactional(propagation = Propagation.REQUIRED)
public void saveLoginInfo(String userName, String dateString, String result) {
String sql = "INSERT INTO prc_mbl_usr_usg (slsprs_id, lgn_dtm, lgn_sts ) VALUES (" + "'" + userName + "'," + "'" + dateString + "'," + "'" + result + "')";
logger.info(sql);
toolsDao.insertUtils(sql);
int m = 1;
if (m == 1) {
throw new RuntimeException();
toolsDao.insertUtils(sql);
抛出异常后,异常前面的insert插入的记录无法回滚,求解
按赞数排序
回滚后,是又插入了吧。
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐博客分类:
FROM:http://mopishv0.blog.163.com/blog/static//
spring的事务管理一般有两种应用方式,即编程式和声明式。大多数情况下我们采用声明式。需要注意一点的是:spring缺省是对java运行时异常和未检查异常进行回滚。其它类型的异常则不回滚。所以不要以为将程序交给spring作事务处理就高枕无忧了!
实际应用用我们往往并不会在意是什么异常才希望事务回滚,而是希望只在程序抛了异常就进行回滚,以便进行处理。所以需要对spring配置作一下修改:
先定义父类
&!--事务代理,如果service需要事务,从此处继承Base TransactionProxyed Service Bean--&
&bean id="baseTxService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"&
&property name="transactionManager" ref="transactionManager" /&
&property name="transactionAttributes"&
&prop key="insert*"&PROPAGATION_REQUIRED&/prop&
&prop key="save*"&PROPAGATION_REQUIRED,-Exception&/prop&
&prop key="update*"&PROPAGATION_REQUIRED&/prop&
&prop key="remove*"&PROPAGATION_REQUIRED&/prop&
&/property&
注意上面的 Java代码
&prop key="save*"&PROPAGATION_REQUIRED,-Exception&/prop&
&prop key="save*"&PROPAGATION_REQUIRED,-Exception&/prop&
“-Exception”表示所有的异常都进行回滚
再定义子类,让它继承上面的父类,这样它也就具有了事务特性:
&bean id="magazineManager" parent="baseTxService"&
&property name="target"&
&bean class="com.harmony.magazine.service.impl.MagazineManager"&
&property name="magazineDao"&
&ref bean="magazineDao" /&
&/property&
&/property&
浏览: 359338 次
来自: 上海
您好,能麻烦您把这个包fisher.man.jce.PKCS1 ...
CPU型号怎么弄?
你好,我需要FishermanJCE,请问能发份这个包给我么? ...
你好,我也需要这个例子的依赖的FishermanJCE相关的包 ...
json序列化反序列化插件-json2.js 介绍和使用 -
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'spring+ibatis事物配置问题为什么只有空指针才回滚,SQLException不回滚 - ITeye问答
&tx:advice id="transactionManagerAdivice"
transaction-manager="transactionManager"&
&tx:attributes&
&tx:method name="insert*" read-only="false" rollback-for="Exception"/&
&tx:method name="update*" read-only="false" rollback-for="Throwable"/&
&tx:method name="save*" read-only="false" rollback-for="Throwable"/&
&tx:method name="*" read-only="true" /&
&/tx:attributes&
&/tx:advice&
&aop:config&
&aop:pointcut
expression="execution(* *..services.impl.*Manager*.*(..))"
id="bankServicePc" /&
&aop:advisor advice-ref="transactionManagerAdivice"
pointcut-ref="bankServicePc" /&
&/aop:config&
问题补充:[color=red]问题解决了
[size=large}catch (SQLException& e) {
&& throw new java.lang.RuntimeException();
}
我在捕获异常的,地方加 throw new java.lang.RuntimeException();
这样就可以解决问题,现在有一个新的疑问,这样写对程序性能有什么影响,这样写好不好?[/[/size]color]
问题补充:zhanjia ,我想假如要扩展RuntimeException类,但是捕捉异常,还是在
(SQLException& e) {
&& throw new RollbackException();
问题补充:之前看到你的信息我写了一个扩展类,觉得意义不大,后面就直接&& throw new java.lang.RuntimeException();&&&
采纳的答案
其实这就像Java中有那么多的扩展异常类一样,每种种异常类用于表示某种异常,一旦你看到Null...Exception你就知道是空指定异常, 这种要体会体会
问题补充:
[color=red]zhanjia ,我想假如要扩展RuntimeException类,但是捕捉异常,还是在
(SQLException& e) {
&& throw new RollbackException();
----------------
是啊,也是这样用,在业务层这样用,即在添加了事务的那一层这样抛出
性能方面没什么问题
建议可以像我上面所说的,扩展一个异常类,用来捕捉需要回滚的地方
* 自定义异常类. 需回滚的方法发生异常时将抛出该异常
* @author qiuzj
@SuppressWarnings("serial")
public class RollbackException extends RuntimeException {
public RollbackException() {
public RollbackException(String message, Throwable cause) {
super(message, cause);
public RollbackException(String message) {
super(message);
public RollbackException(Throwable cause) {
super(cause);
一般开发中都会定义一个扩展自RuntimeException的异常类,如BizException或BusinessException异常类,用在需要进行异常回滚的地方,然后配置:
rollback-for="...BizException"
&& 当事务运行过程中发生异常时,事务可以被声明为回滚或继续提交。
&&& 默认情况下,当发生运行期异常时,事务将被回滚,发生检查型异常时,既不回滚也不提交,控制权交给外层调用。
&&& 这种默认的回滚规则在大多数情况下是适用的。不过用户也可以通过配置显式指定回滚规则:
&&& 通过指定带正号(+)或负号(-)的异常类名(或异常名片断)。当抛出负号型异常时,将触发事务回滚,当抛出正号型异常时,即使这个异常是检查型异常,事务也会提交。抛出异常或其父类异常名匹配规则中指定的异常类名,规则就生效.如:
&prop key="add*"&PROPAGATION_REQUIRED,-Exception&/prop&
只要业务方法运行时抛出的异常或其父类异常的类名包括"Exception",事务就回滚,以下异常都符合这条规则:SQLException、ParseException
&&& 因为spring默认的事务回滚规则为:运行期异常回滚,检查型异常不回滚,所以带负号的异常设置仅对检查型异常有意义.
只有Runtime异常才回滚事务,非运行时异常不回滚事务。
已解决问题
未解决问题博客分类:
最近开发中用到了springjdbctemplate来持久化数据,想通过代码控制事务的回滚和提交,但是所有配置一切正常的情况下就是不能实现回滚,查看了datasource和transactionManager配置都没有问题,但是就不给回滚,手动回滚代码如下:
public void insertUser() {
TransactionTemplate tt = new TransactionTemplate(getTransactionManager());
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jt = new JdbcTemplate(executeTestSource());
jt.execute("insert into `srp_keyword_info` (`kid`, `keyname`, `type`, " +
"`synword`, `srpid`, `differflag`) " +
"values ('11', '1', '11', '1', '1', '1')");
jt.execute("insert into `srp_keyword_info` (`kid`, `keyname`, `type`, " +
"`synword`, `srpid`, `differflag`) " +
"values ('11', '1', '11', '1', '1', '1','2')");
String ss = null;
System.out.println(ss.toCharArray());
return null;
配置正确,但是不回滚这是为什么呢,纠结了一下午,终于找到了答案,原因尽然是:
mysql的表是有事务安全( 比如:InnoDB)和非事务安全(比如:ISAM、MyISAM)之分的,所以你当前表的事务类型是ISAM、或是MyISAM其中的一种,只要修改为InnoDB就可以了,MyISAM是非事务安全的,所以无法实现数据回滚。 只要修改表的类型即可:
alter table tablename type=InnoDb
wanghanchao2012
浏览: 2233 次
来自: 北京
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 sql2005回滚事务 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信