mybatis相同数据更新的实际影响行相同的问题(affectedRows)
参考文档
Mysql Server 官网文档-响应OK_Packet数据包
范围: mybatis相同数据执行2次返回影响行还是一样、有无事务都一样
- 背景介绍
- 过程剖析
- 结论及理解
背景介绍
**添加和去除事务均做尝试:update修改单个字段,mybatis返回2次影响1行,考虑到update为当前读和排他锁特质,怎么会出现类似修改数据副本的情况? **
怀疑点:
- 单update存在隐形事务可能会存在未知的脏读?可是和update当前读的原则互斥
- 排他锁是否生效? 查看事务log及锁占用情况,但无法复现瞬时锁,需要卡锁,依赖事务
- 中间是否被其他语句修改过目标值导致存在影响行?十分确定并检查不存在
过程剖析
- 参考客户端连接对于useAffectedRows解释,返回仅代表匹配行数,只有设置后才是真实影响行数
实际JDBC代码影响行是通过server的OK_Packet获得,jdbc的java 客户端连接类关于连接配置选项:
com.mysql.cj.conf.PropertyKey#useAffectedRows
数据包描述
以下均为:Mysql Server代码
void MySQLServerMockSessionClassic::send_ok(const uint64_t affected_rows,
const uint64_t last_insert_id,
const uint16_t server_status,
const uint16_t warning_count) {
auto buf = protocol_encoder_.encode_ok_message(
seq_no_++, affected_rows, last_insert_id, server_status, warning_count);
send_packet(client_socket_, buf);
}
具体还需要跟:mysql_init(&mysql);
方法,推断在lib库中,此处未继续追,server中未找到useAffectedRows
客户端配置带来的变化----有运维大佬看到可以留言指点
结论及理解
结论:配置jdbc连接字符串带上useAffectedRows即可;确实可以说大部分开发人员都用错了,以为是实际影响行数; 从涉及上来讲确实不太恰当,不知道出于什么样的考量