当前位置:网站首页>解决多线程调用sql存储过程问题
解决多线程调用sql存储过程问题
2022-08-11 04:00:00 【菜鸟是大神】
场景:
我们程序现在改成多线程了,我现在需要把临时表中的数据给插入到TABLE_M中,但这时候可能其他的线程也在插入,我就不能用之前我们的方案了(select max(oid) from Tuning.TABLE_M。。。,之后去维护主子表关系,改掉TABLE_M的OID的自增属性,插入,之后再添加上自增属性。。。。。。)
我现在是想这样操作:
1,)先插入把临时数据插入到TABLE_M(OID是自增的)中(Insert Into ….select …),我之后获取 select Scope_Identity() as @MaxTABLE_MOID,之后根据这个@MaxTABLE_MOID去修改临时表中的TABLE_MOID.
1.1,)(1,)这种方案会不会出现以下问题:
A线程, 1-10 共10条记录,
B 线程,1-10 共10条记录
A线程插入的时候,
B线程也在再插入
A线程 与 B线程是交互的插入,A线程插入一条,B线程插入一条
运行起来像这样:
比如 此时TABLE_M的OID为 100
A线程插入第一条 TABLE_M的OID变为 101
B线程插入第一条 TABLE_M的OID变为 102
当我A线程插入完的时候,我A线程最后一条记录插入的OID为 120
这时候我的Temp 要到这个120 去修改字表关系
TABLE_M(OID=120) 是A 插入的没问题
TABLE_M(OID=119)是B插入的,这时却关联到了A线程对应的临时表的第9条记录
悲哀!!!
1.2,)我们是不是要在插入的时候使用With(lock)
2,)我还有一种想法,就是先插入完成后,根据条件查询出该批数据插入TABLE_M的生成的OID,之后这些OID去和temp匹配(按照顺序匹配,因为插入temp肯定是有序的插入),之后修改temp中的TABLE_MOID,这样就可以把子数据插入到TABLE_M_LteCell,TABLE_M_GsmCell,TABLE_M_TdsCell中。
DBA提供解决方案
我们可以单独做一个表来进行OID自增的维护,可以暂时称为MAX_OID表。最简单的方式是里面仅仅记录:当前最大的OID。
这样我们在做多线程操作的时候遵循以下步骤
1. 取得MAX_OID表中的值,这样就可以获得自增的起始序列号
2. 获得此次插入时候的临时表的最大行数。不要使用select count(1) from table,使用如下语句,可以获得最大的性能。
直接获取表行数sql语句:
select sum(row_count)
from sys.dm_db_partition_stats
where index_id<1 and object_id=object_id('表名')
3. 使用max_oid+临时表的表行数,可以得到将临时表插入到主表之后,主表未来最大的MAXOID号
4. 更新MAX_OID表。将表内数据改为:max_oid+临时表的表行数
特别注意:为了保证事务一致性,上述步骤需要在一个事务中完成,需要以下语句
SET XACT_ABORT ON
begin tran
执行的sql语句(即上面1-4的逻辑操作)
commit
以上四个步骤虽然文字上比较啰嗦,但是实际操作会非常快。使用的全是系统表来读取,肯定是在毫秒级别,不会影响性能。
这样,每个线程读取的都是MAX_OID表中的值,就不会产生冲突了。
如下面的例子:
目前MAX_OID 最大值为100.
线程一的临时表为30行
线程二的临时表为40行
线程一:
1.读取MAX_OID 表。得到100
2.获得临时表行数:30
3.得到预测的maxoid为100+30=130
4.将MAX_OID 更改为130.
线程二:
1.读取MAX_OID 表。得到130
2.获得临时表行数:40
3.得到预测的maxoid为130+40=170
4.将MAX_OID 更改为170.
注意:线程二得到的MAX_OID 一定是130,而不是100.因为线程一已经更新了这个值。且更新的过程中加锁。线程二是读取不到100这个数值的。
这样就可以避免冲突了。
边栏推荐
- Rotary array problem: how to realize the array "overall reverse, internal orderly"?"Three-step conversion method" wonderful array
- 【FPGA】SDRAM
- What is Machine Reinforcement Learning?What is the principle?
- The impact of programmatic trading and subjective trading on the profit curve!
- 【力扣】22.括号生成
- .NET Custom Middleware
- Alibaba Cloud releases 3 high-performance computing solutions
- FTP错误代码列表
- es-head plugin insert query and conditional query (5)
- Design and Realization of Employment Management System in Colleges and Universities
猜你喜欢
Interchangeable Measurement Techniques - Geometric Errors
多串口RS485工业网关BL110
【C语言】入门
【深度学习】基于卷积神经网络的天气识别训练
leetCode刷题14天二叉树系列之《 110 平衡二叉树判断》
Multi-serial port RS485 industrial gateway BL110
Day20 FPGA 】 【 - block the I2C read and write EEPROM
"239 Sliding Window Maximum Value" on the 16th day of LeetCode brushing
EasyCVR接入GB28181设备时,设备接入正常但视频无法播放是什么原因?
CTO said that the number of rows in a MySQL table should not exceed 2000w, why?
随机推荐
[Likou] 22. Bracket generation
Binary tree related code questions [more complete] C language
【人话版】WEB3将至之“权益的游戏”
MySQL数据库存储引擎以及数据库的创建、修改与删除
[ADI low-power 2k code] Based on ADuCM4050, ADXL363, TMP75 acceleration, temperature detection and serial port printing, buzzer playing music (lone warrior)
The thirteenth day of learning programming
The last update time of the tables queried by the two nodes of the rac standby database is inconsistent
A brief analysis of whether programmatic futures trading or manual order is better?
.NET Custom Middleware
shell monitors gpu usage
【FPGA】day20-I2C读写EEPROM
C# 一周入门高级编程之《C#-LINQ》Day Four
LeetCode刷题第12天二叉树系列之《104 二叉树的最大深度》
[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface
LeetCode814算题第15天二叉树系列值《814 二叉树剪枝》
【ADI低功耗2k代码】基于ADuCM4050的ADXL363、TMP75的加速度、温度检测及串口打印、蜂鸣器播放音乐(孤勇者)
每日一题-滑动窗口
【FPGA】day18-ds18b20实现温度采集
CTO said that the number of rows in a MySQL table should not exceed 2000w, why?
console.log alternatives you didn't know about