当前位置:网站首页>我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
2022-06-27 08:26:00 【InfoQ】
一、前言:一个Bug
没想到一个Bug,竟然搞我两次!

- 就是这个 selectKey 的配置,在执行插入SQL后,开始执行获取最后的索引值。
- 通常只要配置的没问题,返回对象中也有对应的 id 字段,那么就可以正确的拿到返回值了。PS:问题就出现在这里,小傅哥手写的 Mybatis 竟然只难道返回一个0!
二、分析:诊断异常

- Mybatis 的处理过程可以分为两个大部分来看,一部分是解析,另外一部分是使用。解析的时候把 Mapper XML 中的 insert 标签语句解析出来,同时解析 selectKey 标签。最终解析完成后,把解析的语句信息使用 MappedStatement 映射语句类存放起来。便于后续在 DefaultSqlSession 执行操作的时候,可以从 Configuration 配置项中获取出来使用。
- 那么这里有一个非常重要的点,就是执行 insert 插入的时候,里面还包含了一句查询的操作。那也就是说,我们会在一次 Insert 中,包含两条执行语句。重点:bug就发生在这里,为什么呢?因为最开始这两条语句执行的时候,在获取链接的时候,每一条都是获取一个新的链接,那么也就是说,insert xxx、select LAST_INSERT_ID() 在两个 connection 连接执行时,其实是不对的,没法获取到插入后的索引 ID,只有在一个链接或者一个事务下(一次 commit)才能有事务的特性,获取插入数据后的自增ID。
- 而因为这部分最开始手写 JdbcTransaction 实现 Transaction 接口获取连接的时候,每一次都是新的链接,代码块如下;
- 这里的链接获取,最开始没有 if null 的判断,每次都是直接获取链接,所以这种非一个链接下的两条 SQL 操作,所以必然不会获得到正确的结果,相当于只是单独执行
SELECT LAST_INSERT_ID()
所以最终的查询结果为 0 了就!你可以测试把这条语句复制到 SQL查询工具中执行
三、震惊:同一个坑

四、常见:事务失效
- 数据库引擎不支持事务:这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。https://dev.mysql.com/doc/refman/8.0/en/storage-en...从 MySQL 5.5.5 开始的默认存储引擎是:InnoDB,之前默认的都是:MyISAM,所以这点要值得注意,底层引擎不支持事务再怎么搞都是白搭。
- 方法不是 public 的:来自 Spring 官方文档【When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.】@Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
- 没有被 Spring 管理:
// @Service - 这里被注释掉了 public class OrderServiceImpl implements OrderService { @Transactional public void placeOrder(Order order) { // ... } }
- 数据源没有配置事务管理器:一般来自于自研的数据库路由组件
@Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }
- 异常被吞了。catch 后直接吃了,事务异常无法回滚。同时要配置上对应的异常
@Transactional(rollbackFor = Exception.class)
五、总结:学习经验
边栏推荐
- MATLAB小技巧(19)矩阵分析--主成分分析
- Redis的持久化机制
- 2022 love analysis · panoramic report of it operation and maintenance manufacturers
- LVGL GUI GUIDER移植代码到STM32
- [cloud native] 2.3 kubernetes core practice (Part 1)
- 分析日志.log
- Rough reading DS transunet: dual swing transformer u-net for medical image segmentation
- orthofinder直系同源蛋白分析及结果处理
- Lvgl GUI guide porting code to stm32
- Rust async: SMOL source code analysis -executor
猜你喜欢
数字IC-1.9 吃透通信协议中状态机的代码编写套路
SPARQL基础入门练习
Zabbix部署说明(Server+Win客户端+交换机(H3C))
参考 | 升级 Win11 移动热点开不了或者开了连不上
盲測調查顯示女碼農比男碼農更優秀
0号进程,1号进程,2号进程
webrtc入门:12.Kurento下的RtpEndpoint和WebrtcEndpoint
Refer to | the computer cannot access the Internet after the hotspot is turned on in win11
[batch dos-cmd command - summary and summary] - map folder to virtual disk - subst
ServletConfig and ServletContext
随机推荐
针对直播痛点的关键技术解析——首帧秒开、清晰度、流畅度
【云原生】2.3 Kubernetes 核心实战(上)
Understanding mvcc in MySQL transactions is super simple
Refer to | the computer cannot access the Internet after the hotspot is turned on in win11
Rough reading DS transunet: dual swing transformer u-net for medical image segmentation
(note) Anaconda navigator flashback solution
JVM常见的垃圾收集器
How much do you know about the cause of amplifier distortion?
PayPal account has been massively frozen! How can cross-border sellers help themselves?
CLassLoader
Pin details in rust
oracle怎样将字符串转为多行
Recognize the ordering of O (nlogn)
[batch dos-cmd command - summary and summary] - map folder to virtual disk - subst
UE5神通--POI解决方案
DataV轮播表组件dv-scroll-board宽度问题
RMAN-08137 主库无法删除归档文件
Chapter 11 signal (I) - concept
100%弄明白5种IO模型
Eight misunderstandings, broken one by one (final): the cloud is difficult to expand, the customization is poor, and the administrator will lose control?