spring@Transactional /TransactionTemplate开发周总结

spring事务的回滚,方法中只要有truncate ,全都回滚失效。所以吖,要在事务结束后,根据事务的状态是否回滚,做truncate操作,因为mysql truncate 没有事务。代理里要写在trycatch 之后的finally 里面。

spring事务的使用,有三种方式。

1】.@Transactional注解

使用该注解,必需要在spring管理的bean 中使用,可使用在类/方法上。需要注意:方法包含try ..catch ,该注解失效。以及多线程下,该注解失效。一般用在dao层或者使用mybatis,就用在mapper调用的service层。

事务注解要在public 方法上才生效

springboot+mybatis 事务失效的原因:springboot 默认提供的事务是jpa,你用的是mybatis,要加bean  DtataSourceTransactionManager.

2】.TransactionTemplate(使用此方法,注意别嵌套,容易出二次异常unexpectedrollbackexception)

多线程以及try catch 中可以使用该方式。但是要注意,transactionTemplate.execute();不要重复嵌套使用,容易抛异常。unexpectedrollbackexception;; 解决方式其中一种是使用try catch 。

如果只是单事务的情况下,第一层简单操作使用@transactional ,第二层业务逻辑使用TransactionTemplate,第三层使用TransactionTemplate,然后第二层套异常,直接catch,然后里面再使用status.setRollBackOnly(),这个异常不是sql异常,就会触发unexpectedrollbackexception异常。

解决方式:第三层添加trycatch ,第三层代码:

举个栗子:

int num=0;

try{

num=service.add();

}catch(Exception e)

{

...log

}

然后如果catch里面没有return ;或者continue;那么代码会继续执行下去。

事务的循环就需要这样的trycatch 机制,让事务循环起来。

记住事务的循环,回滚了要记得continue;还要干下一条呢。

ps 与事务无关的跳出foreach 循环的方式,使用break无效,要在foreach 或者list.for (for(int i :list))最外层添加try,catch .循环体中throw new RunTimeException() 跳出循环。

unexpectedrollbackexception 异常解决方式总结:

1.异常机制:第三层用try /catch 

2.判断是否sql异常:第二层catch(Expection e){ if(e instanceof SQLException){}  }

3.第二层可以去掉TransactionTemplate 也可以解决这个异常。

4.如果线程运行异常就结束,这个异常算二次异常,没有影响业务也可以不处理。

5.如果希望内层事务回滚,但不影响外层事务提交,需要将内层事务的传播方式指定为PROPAGATION_NESTED。注:PROPAGATION_NESTED基于数据库savepoint实现的嵌套事务,外层事务的提交和回滚能够控制嵌内层事务,而内层事务报错时,可以返回原始savepoint,外层事务可以继续提交。

3】.aop+transaction

两种方式:xml /java代码,使用这个最方便快捷。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值