MYSQL下数据库事务是如何处理这个场景的?请教各位大虾

findshine 2016-03-03 10:21:53
批次表(P)
字段:ID,detailCount(统计每批次总数)

条码表(I)
字段:ID,fromCount,toCount,totalCount,P_id

实现业务:
插入数据到条码表,插入之前先去批次表插入一条批次明细,并得到批次ID,然后再去批次表读取sum(detailCount),得到起始Count和结束Count。

实现场景:
P表数据:
1 100
2 100
3 500

此时,比如要插入200个条码,则先去P表插入一条数据(detailCount=500),此时会返回ID=4,然后在用ID=4去汇总(select sum(detailCount) from p where id<4)得到700,然后插入条码表inert into I(fromCount,toCount,totalCount,P_id)values(700,900,200,4)


问题来了(如下业务场景都建立在数据库事务的前提下):
假如有A场景正在执行如上业务,并得到ID=4,然后正在执行条码表的插入操作,未结束的过程中,B场景也进来了 也执行同样的业务。

因为事务是整段执行完之后如果没异常才提交,如果有异常就回滚,
1、那么B场景进来的时候是不是会读取到批次ID=4?还是ID=5?
2、如果AB几乎是同时执行,且A执行过程中B场景也进来的,那么如果A场景执行失败并回滚了,那么B怎么办?B最终从批次表得到批次ID究竟是4还是5?

感谢各位大虾指教
...全文
128 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
fcy_n 2016-03-07
  • 打赏
  • 举报
回复
这个要看批次表的ID是不是自增的了,是的话,只能增,不能减
LongRui888 2016-03-07
  • 打赏
  • 举报
回复
1、那么B场景进来的时候是不是会读取到批次ID=4?还是ID=5? 应该是5. 2、如果AB几乎是同时执行,且A执行过程中B场景也进来的,那么如果A场景执行失败并回滚了,那么B怎么办?B最终从批次表得到批次ID究竟是4还是5? 还是5. P表的id是自增列是把,这个并发的控制是由mysql来实现的。 一般会在内存中存储一个缓冲的id值,当有多个并发的会话要同时插入,mysql会分配自增id值。 从系统实现上来说,应该是系统内部有一个自增id值的数据,会记录当前 xx表的id是多少,然后当有2个并发会话都是插入数据,俺么这两个线程都要访问这个id当前是什么值,当时同一时间只能由一个线程能访问到,于是发现当前是3,于是自增1,也就是4,在同时另一个回话会被阻塞住,当前面的会话获取了id之后,他发现现在是4,于是自增到5. 当最后没有提交的时候,也不会修改为4,因为 在5已经出现在系统缓存中,所以 数字是不断增长的,实际上有时候,就算你不回滚,2个会话都是提交的,也会出现 id值不连续的情况。
ACMAIN_CHM 2016-03-03
  • 打赏
  • 举报
回复
1、那么B场景进来的时候是不是会读取到批次ID=4?还是ID=5? ID=5 2、如果AB几乎是同时执行,且A执行过程中B场景也进来的,那么如果A场景执行失败并回滚了,那么B怎么办?B最终从批次表得到批次ID究竟是4还是5? 是5

56,687

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧