千家信息网

Mysql数据库数据更新失效的原因和解决方法

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关Mysql数据库数据更新失效的原因和解决方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 背景最近的项目中遇到一项问题,并发更新某
千家信息网最后更新 2026年11月02日Mysql数据库数据更新失效的原因和解决方法

这篇文章将为大家详细讲解有关Mysql数据库数据更新失效的原因和解决方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1. 背景

最近的项目中遇到一项问题,并发更新某一单据的时候,出现了更新失效的情况。比如:

@Transactional(rollbackFor = Exception.class)public void update(Integer id){    //1.按id查询    //2.更新某一字段的值}

生成的SQL大概是这样的:

UPDATE  table SET field = #{field,jdbcType=INTEGER}WHERE id= 1

那么以上代码产生的问题就是:
对于同一个id=1来说,请求A与请求B都进到了update方法中,此时按id查询得到的信息是相同的,那么请求A更新了id=1的这条记录之后,此时,请求B又对id=1的记录进行更新,此时注意请求B更新id=1的记录的时候,请求B按id查询到的数据已经是旧数据了,请求B执行完之后,请求A的更新被请求B覆盖了。

如果更新的是状态,那倒无所谓,如果库存量呢?
如果更新的是库存,是在这条记录的原始值上进行+或者-操作,是不是就出问题了?

2. 分析产生的原因

事后写了个小demo来复现问题,代码大致如下:

需求: 某个分类每被访问一次,排序就+1;
开启两个客户端同时访问

@Transactional(rollbackFor = Exception.class)public void updateStatusTest(Integer id) {    System.out.println("start:"+Thread.currentThread().getName());    Category category = categoryMapper.selectById(id);    try {        Thread.sleep(8000);    } catch (InterruptedException e) {        e.printStackTrace();    }    System.out.println(Thread.currentThread().getName()+":"+category);    category.setSort(category.getSort()+1);    categoryMapper.updateById(category);    category = categoryMapper.selectById(id);    System.out.println(Thread.currentThread().getName()+":"+category);    System.out.println("end:"+Thread.currentThread().getName());}

DAO层使用的mybatis,生成日志大致如下:
需要更新的sort值数据库初始为:0

start:http-nio-8062-exec-1Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9]JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@2d5c951c] will be managed by Spring==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=? ==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 0, 1111<==      Total: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9] Time:27 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,        parent_id,        image_url,        icon_url,        sort,        status     FROM        t_admin_category     WHERE        cid=6start:http-nio-8062-exec-2Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046]JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@700c5b36] will be managed by Spring==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=?  Time:2 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,        parent_id,        image_url,        icon_url,        sort,        status     FROM        t_admin_category     WHERE        cid=6==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 0, 1111<==      Total: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046]http-nio-8062-exec-1:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=0, status='1111'}Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9] from current transaction==>  Preparing: UPDATE t_admin_category SET category_name=?, parent_id=?, image_url=?, icon_url=?, sort=?, status=? WHERE cid=? ==> Parameters: 1(String), 0(Integer), 11111(String), 1(String), 1(Integer), 1111(String), 6(Integer) Time:16 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.updateByIdExecute SQL:    UPDATE        t_admin_category     SET        category_name='1',        parent_id=0,        image_url='11111',        icon_url='1',        sort=1,        status='1111'     WHERE<==    Updates: 1        cid=6Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9] Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9] from current transaction    SELECT        cid,        category_name,==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=?         parent_id,==> Parameters: 6(Integer)        image_url,        icon_url,<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status        sort,        status <==        Row: 6, 1, 0, 11111, 1, 1, 1111    FROM<==      Total: 1        t_admin_category     WHEREReleasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9]        cid=6http-nio-8062-exec-1:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=1, status='1111'}end:http-nio-8062-exec-1Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9]Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9]Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6df7e3e9]http-nio-8062-exec-2:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=0, status='1111'}Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046] from current transaction==>  Preparing: UPDATE t_admin_category SET category_name=?, parent_id=?, image_url=?, icon_url=?, sort=?, status=? WHERE cid=?  Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.updateByIdExecute SQL:    UPDATE        t_admin_category     SET        category_name='1',        parent_id=0,        image_url='11111',        icon_url='1',        sort=1,        status='1111'     WHERE        cid=6==> Parameters: 1(String), 0(Integer), 11111(String), 1(String), 1(Integer), 1111(String), 6(Integer)<==    Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046]Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046] from current transaction==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=? ==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 0, 1111 Time:16 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,<==      Total: 1        parent_id,        image_url,Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7af43046]        icon_url,        sort,        status     FROMhttp-nio-8062-exec-2:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=0, status='1111'}        t_admin_category end:http-nio-8062-exec-2    WHERE        cid=6

大致意思:
请求A与请求B,同时操作id=6的这条记录时,查询出来id=6的这条记录,然后请求A对其进行了修改 SET sort=1操作,完事之后,请求A的事务提交了。而此时请求B,通过id=6条件查询到的category的信息是请求A提交之前的,此时请求B执行了SET sort=1,覆盖了请求B的修改操作。

3. 解决思路

解决方法其它很简单,我们上面可以看到,update语句是直接set sort=1的,我们只需要改为set sort = sort +1 就可以了。你不信?那我改一下试试:

@Transactional(rollbackFor = Exception.class)public void updateStatusTest(Integer id) {    System.out.println("start:"+Thread.currentThread().getName());    Category category = categoryMapper.selectById(id);    try {        Thread.sleep(8000);    } catch (InterruptedException e) {        e.printStackTrace();    }    System.out.println(Thread.currentThread().getName()+":"+category);//        category.setSort(category.getSort()+1);    categoryMapper.updateStatusById(category);    category = categoryMapper.selectById(id);    System.out.println(Thread.currentThread().getName()+":"+category);    System.out.println("end:"+Thread.currentThread().getName());}

Mapper文件:

      UPDATE        t_admin_category      SET        sort =sort + 1    WHERE        cid= #{cid,jdbcType=INTEGER}

我们执行试一下,看下日志:

start:http-nio-8062-exec-1Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@6c17839b] will be managed by Spring==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=? ==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 0, 1111<==      Total: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f] Time:43 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,        parent_id,        image_url,        icon_url,        sort,        status     FROM        t_admin_category     WHERE        cid=6start:http-nio-8062-exec-2Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022]JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@195f8b5a] will be managed by Spring==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=? ==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 0, 1111<==      Total: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022] Time:2 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,        parent_id,        image_url,        icon_url,        sort,        status     FROM        t_admin_category     WHERE        cid=6http-nio-8062-exec-1:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=0, status='1111'}Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f] from current transaction==>  Preparing: UPDATE t_admin_category SET sort =sort + 1 WHERE cid= ? ==> Parameters: 6(Integer)<==    Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f] from current transaction==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=?  Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.updateStatusByIdExecute SQL:    UPDATE        t_admin_category     SET        sort =sort + 1     WHERE        cid= 6==> Parameters: 6(Integer) Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectById<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, statusExecute SQL:<==        Row: 6, 1, 0, 11111, 1, 1, 1111    SELECT<==      Total: 1        cid,Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]        category_name,        parent_id,http-nio-8062-exec-1:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=1, status='1111'}        image_url,end:http-nio-8062-exec-1        icon_url,        sort,Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]        status     FROMTransaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]        t_admin_category     WHERETransaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e925f3f]        cid=6 Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.updateStatusByIdExecute SQL:    UPDATE        t_admin_category     SET        sort =sort + 1     WHERE        cid= 6 Time:0 ms - ID:com.sxl.simple.shop.admin.category.mapper.CategoryMapper.selectByIdExecute SQL:    SELECT        cid,        category_name,        parent_id,        image_url,        icon_url,        sort,        status     FROM        t_admin_category     WHERE        cid=6http-nio-8062-exec-2:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=0, status='1111'}Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022] from current transaction==>  Preparing: UPDATE t_admin_category SET sort =sort + 1 WHERE cid= ? ==> Parameters: 6(Integer)<==    Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022]Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022] from current transaction==>  Preparing: SELECT cid,category_name,parent_id,image_url,icon_url,sort,status FROM t_admin_category WHERE cid=? ==> Parameters: 6(Integer)<==    Columns: cid, category_name, parent_id, image_url, icon_url, sort, status<==        Row: 6, 1, 0, 11111, 1, 2, 1111<==      Total: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c88f022]http-nio-8062-exec-2:Category{cid=6, categoryName='1', parentId=0, imageUrl='11111', iconUrl='1', sort=2, status='1111'}end:http-nio-8062-exec-2

看完上述内容,你们对Mysql数据库数据更新失效的原因和解决方法大概了解了吗?如果想了解更多相关文章内容,欢迎关注行业资讯频道,感谢各位的阅读!

更新 数据 查询 方法 问题 原因 数据库 代码 信息 内容 同时 库存 日志 时候 篇文章 生成 原始 实用 相同 无所谓 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳恒合互联网络科技有限公司 奇酷互联网科技公司 世界互联网领先科技成果 凡科互联网科技 华中科技大学互联网 上游互联网科技 中国互联网金融科技基金 富国互联网科技创新基金 成都玖崟互联网科技有限公司乐商圈怎么样 栖莱科技互联网股份有限公司 畅思互联网科技 高科技互联网发展前景如何 朱啸虎曾投资哪些互联网科技企业 山东星卡互联网科技有限公司官网 互联网公司高科技产品 半导体行业属于互联网高科技类吗 易租星互联网科技有限公司 银川新华互联网科技学校原画 平安好医生打造互联网科技医疗 前海云享互联网科技 美国互联网保险保险科技 金诺互联网科技 衡水科技产业互联网平台 来此购互联网科技有限公司 互联网科技商业 电子科技大学互联网创业大赛 郑州欣桑互联网科技有限公司 萌小萌互联网科技河南有限公司 中国新注册互联网科技 前海云享互联网科技
0