首页 > 编程知识 正文

spring中常用的注解以及作用,@transactional注解是用aop实现的

时间:2023-05-04 13:35:52 阅读:106043 作者:899

文章首发于个人博客,欢迎访问关注:https://www.lin2j.tech

今天,在开发中发现了问题。 原来的逻辑是用方法进行网络请求,成功后将记录插入数据库。

但实际测试表明,即使网络请求失败,也会插入数据库。

加了@Transactional注释,但好像没有效果。

部分代码如下所示

@ overridepublicvoidbindchannel (tvwallchannelbinddtodto ) tvwallchannelconfigentity=dto.to entity ); 检查绑定(dto; decoderinfodecoder=get decoder (dto.getdecodersbbm ); objects.is null (decoder ) { throw new BizException ) (“编码器不存在”); } dischannelinfochannelinfo=dischannelinfomapper.querybyconfig (entity ); if (objects.is null (信道信息) ) { throw new BizException ) (“通道不存在”); }bind(entity,decoder ); } @ transactional (roll back for=exception.class ) publicvoidbind ) tvwallchannelconfigentity, DecoderInfo decoder ) Tvwaaactional //以下称为网络请求信道分发(entity.getwindow no )、decoder、entity.getChannelNo }如上所述,我们认为打开事务可以在出现异常时回滚,而无需仔细考虑代码逻辑的优先级。

但是,如果@Transactional注释失效了,我没有意识到有什么,但这里包含了一种。

因此,通过谷歌搜索查找@Transactional失效的情况时,发现有以下使用规则。

使用@Transactional注释的方法必须是公共的。 如果添加到protected、private或package可以显示的方法中,则不会生效,也不会报告错误。 @Transactional缺省回退RuntimeException,但如果还需要回退其他异常,可以通过设置rollbackFor属性来实现。 @ transactional (roll back for=exception.class )。 如果在方法内部通过try.catch删除了异常,则不会回滚事务。 Springboot项目缺省支持事务,不需要配置; 对于其他类型的项目,必须设置是否在xml中打开事务。 检查自己的数据库是否支持MySQL的mylsam等事务。 同一类中除@Transaction以外的方法调用中包含@Transaction的方法由于代理问题而无效。 这里头五点我没有违反。 只有六点。 适合我的情况。

知道原因后,只需简单调整bind ()方法即可。

//@ transactional (roll back for=exception.class ) publicvoidbind ) tvwallchannelconfigentity,DecoderInfo decoder ) chall DecoderInfo decoder ) Ctvwallchannelconfigmapper.insert (entity ) }这里之所以能做到,是因为插入数据库本来应该在网络请求成功之后进行。 如果失败,则会发生异常,直接结束方法。

以前也是因为自己的疏忽引起了这个问题。

为什么没加 @Transactional 的方法调用加了 @Transactional 注解的方法时,不会开启事务?

首先,在添加@Transactional注释后,必须知道Spring通过AOP来增强类或方法。

具体来说,通过生成代理类,在调用实际方法之前打开事务,调用实际方法。

问题就在这里。 调用实际方法的方法是在代理类中创建未扩展的对象。 也就是说,我们实际编码写的类的实例没有扩展。 我们是怎么写的,那是什么样的?

bind ) )方法中添加了@Transactional注释时,该注释看起来无效,因为没有为实际对象打开事务。

辅助示例:

@ servicepublicclassa { public void a () ) b ); } @transactional (roll back for=exception.calss ) public void b ) ) { }}//Spring扫描以生成@Service和@ transactional注释}扫描到公共void b (()//b的方法包括@Transactional注释,事务startTransactinal ); obj.b (; 请注意,Proxy$A不会调用a (调用方法时,为增强的b )方法。

我认为解决方法可以使用以下几种

将这两种方法划分为单独的类,并在类名中添加注释以调整代码的逻辑顺序,并尽可能向后移动数据库操作,而不影响正常逻辑

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。