局域网下简易多人自动编号方法分享,适合单客户端、非OpenQQ机制的狐表应用

发表日期: 2022-07-21

1.需求说明

        想做一个局域网多人用的系统,但是不想上OpenQQ这种“服务器+客户端”双程序维护的模式,想直接利用Access数据库+单客户端

        其中会遇到一个问题:就是如何多人下并发新增时生成不重复编号?

2.常见的错误思路

2.1错误思路1:在DataRowAdding事件里使用identify列。

这个字段在新增的时候不存在,保存后会发生变化,并不合适做自增字段,见下图

e.DataRow("编号")= e.DataRow("identify")

image.png

image.png

而且identify字段在表迁移的时候,还会自动重新计算,用它做自动编号,就是非常不靠谱的

image.png

2.2错误思路2:直接使用SqlCompute+1

e.DataRow("编号")= e.DataTable.SqlCompute("Max(编号)") +1

并发下直接死掉,肯定重复的

3.正确思路

参考狐表文档的《网络环境下的复杂编号》思路,我在基础上进一步精简代码,更加便捷易用

3.1建立表,名称:自动编号表

image.png

3.2新建自定义内部函数,名称:获取自动编号

'通过Functions.Execute("获取自动编号","表名")使用
'传入表名,返回这个表当前可用的新自增编号
'思路参考狐表官方文档《网络环境下的复杂编号》,实测异步并发生成也不会有重复编号

Dim tableName As String = Args(0)

Dim cmd As New SQLCommand
cmd.ConnectionName = "DB" '数据库源名称 
cmd.commandText = "Select Count(*) From 自动编号表 Where 表名 = '" & tableName & "'"
If cmd.ExecuteScalar = 0 Then '如果编号表不存在该表名的记录,那么增加一行
    cmd.commandtext = "Insert Into 自动编号表 (表名, 当前编号) Values('" & tableName & "',1)"
    cmd.ExecuteNonQuery
End If

Dim No As Integer 
Do
    '1从后台获取当前最新编号
    cmd.commandText = "Select 当前编号 From 自动编号表 Where 表名 = '" & tableName & "'" 
    No = cmd.ExecuteScalar()

    '2尝试更新编号,确保编号可用
    cmd.commandText = "Update 自动编号表 Set 当前编号 = " & (No + 1) & " Where 当前编号 = " & No & " And 表名 = '" & tableName & "'"
    Try '超过数据库并发承受力,会出现“行被锁定,无法更新”,要能捕获错误并跳过继续尝试
        If cmd.ExecuteNonQuery() > 0 Then '更新编号
            Exit Do '更新成功,说明编号可用,则退出循环
        End If
    Catch ex As Exception
    End Try
Loop 

Return No

3.3在业务表的DataRowAdding事件

e.DataRow("编号") = Functions.Execute("获取自动编号", e.DataTable.Name)

3.4即可得到以下效果

image.png

3.5双程序异步并发取号 压力测试——通过

image.png

image.png


随便看看

Copyright © 2016-2022 江门蓬江区华越科技公司 版权所有 | 承接软件定制开发,欢迎联系
粤ICP备17073215号