当前位置:网站首页>解决多线程调用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这个数值的。
这样就可以避免冲突了。
边栏推荐
- C语言 recv()函数、recvfrom()函数、recvmsg()函数
- Which one to choose for mobile map development?
- 【FPGA】day18-ds18b20实现温度采集
- leetCode刷题14天二叉树系列之《 110 平衡二叉树判断》
- 【FPGA】day20-I2C读写EEPROM
- The solution to the height collapse problem
- Getting Started with Raspberry Pi (5) System Backup
- 华南师范宋宇老师课堂对话论文翻译
- When EasyCVR is connected to the GB28181 device, what is the reason that the device is connected normally but the video cannot be played?
- Common layout effect realization scheme
猜你喜欢
LeetCode814算题第15天二叉树系列值《814 二叉树剪枝》
校园兼职平台项目反思
leetCode刷题14天二叉树系列之《 110 平衡二叉树判断》
【FPGA】day19-二进制转换为十进制(BCD码)
Kubernetes集群搭建Zabbix监控平台
leetcode刷题第13天二叉树系列之《98 BST及其验证》
Graphical LeetCode - 640. Solving Equations (Difficulty: Moderate)
【FPGA】设计思路——I2C协议
What should I do if the channel ServerID is incorrect when EasyCVR is connected to a Hikvision Dahua device and selects another cluster server?
Is Redis old?Performance comparison between Redis and Dragonfly
随机推荐
typedef defines the structure array type
When EasyCVR is connected to the GB28181 device, what is the reason that the device is connected normally but the video cannot be played?
Differences and connections between distributed and clustered
Watch to monitor
Rotary array problem: how to realize the array "overall reverse, internal orderly"?"Three-step conversion method" wonderful array
C language recv() function, recvfrom() function, recvmsg() function
使用jackson解析json数据详讲
Design and Realization of Employment Management System in Colleges and Universities
Pinduoduo store business license related issues
这些云自动化测试工具值得拥有
What are port 80 and port 443?What's the difference?
Use jackson to parse json data in detail
【FPGA】名词缩写
"98 BST and Its Verification" of the 13th day of leetcode brushing series of binary tree series
"125 Palindrome Verification" of the 10th day string series of LeetCode brushing questions
Get the length of the linked list
uni-app - 城市选择索引列表 / 通过 A-Z 排序的城市列表(uview 组件库 IndexList 索引列表)
Build Zabbix Kubernetes cluster monitoring platform
Audio codec, using FAAC to implement AAC encoding
Is there any way for kingbaseES to not read the system view under sys_catalog by default?