批次表(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?
感谢各位大虾指点
字段: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?
感谢各位大虾指点
解决方案
55
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值不连续的情况。
应该是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值不连续的情况。
20
这个要看批次表的ID是不是自增的了,是的话,只能增,不能减