简体   繁体   English

避免多个用户使用事务插入相同的号码

[英]Avoid to insert same number by multiple users using transaction

I have couple insert queries which are merged into transaction scope. 我有几个插入查询,这些查询已合并到事务范围中。 First of that insert is to create new product article number which is built by incrementing of the highest in table by one. 该插入的第一步是创建新产品商品编号,该商品编号是通过将表格中的最高位加1来构建的。 Unfortunately I just noticed that mostly during tests if for instance two users from two different applications clicks button which trigger my transaction's method they could get same new product number and insert it. 不幸的是,我只是注意到,在测试过程中,例如,如果来自两个不同应用程序的两个用户单击触发我的交易方法的按钮,他们可能会获得相同的新产品编号并将其插入。 How can I avoid that situation? 我如何避免这种情况?

Part of my transaction query below: 我的部分交易查询如下:

Public Sub ProcessArticle(ByRef artikel As ArticlesVariations)
        Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(System.String)).ToString()
        Using connection As New SqlConnection(strcon)
            connection.Open()
            Using transaction = connection.BeginTransaction()
                Try

                            Using cmd As New SqlCommand("INSERT INTO tbArtikel (Nummer) VALUES (@Nummer);Select Scope_Identity()", transaction.Connection)
                                cmd.CommandType = CommandType.Text
                                cmd.Connection = connection
                                cmd.Transaction = transaction

                                 'Get next product number from table tbArtikel  (this will be new product number)'
                                 Dim NewArtNummer as String =  New DALArtikel().GetNewArtikelNumber(transaction)
                                 art.Nummer = NewArtNummer

                                cmd.Parameters.AddWithValue("@Nummer", art.Nummer)
'Get inserted product id for other diffrent inserts below'
 newArticleRowId = CInt(cmd.ExecuteScalar()) 

'....
other INSERTs queries to other tables ...
...'

       transaction.Commit()
                Catch ex As Exception
                    transaction.Rollback()
                    Throw 'Rethrow exception.'
                End Try
            End Using
        End Using
    End Sub

Article number is varchar column (I know it's bad etc) but it is how its implemented in current scope without possibility to change it. 文章编号是varchar列(我知道它不好,等等),但这是它在当前范围内如何实现而无法更改的方式。

Note that I cannot do any changes on the database level like new tables, trigger etc. (one exception is to create unique index on number column). 请注意,我无法在数据库级别进行任何更改,例如新表,触发器等(一个例外是在number列上创建唯一索引)。 I have to achieve that from application level. 我必须从应用程序级别实现。

I got three options on top of my mind and would like to take your advice which to choose: 我想到了三个选择,并希望采纳您的建议以供选择:

1st option: 第一种选择:

a) Make this column as unique column so when couple users inserting only one will insert the number but all of rest users will get error from catch about unique key violation so i could manage it somehow like make information to retry again. a)将此列设置为唯一列,以便当情侣用户仅插入一个时将插入该数字,但所有其余用户将从捕获到的唯一键冲突中得到错误,因此我可以进行某种处理,例如使信息重试。

b) Same as a) but also with isolation level set to ReadUncommited - from my point of view this will give me that when next users read newnumber they have chance to read from dirty numbers (so also from first user insertion) so there is chance they get next number. b)a)相同,但隔离级别设置为ReadUncommited-从我的角度来看,这将使我知道,当下一个用户读取newnumber时,他们有机会从脏号码中读取(也从第一次插入用户中读取),因此有机会他们得到下一个号码。

2nd option: 第二个选择:

Just to make transaction isolation to Read uncommitted - but this will not guaranty all same line users would get new number (probably worst out of all) 只是为了使事务隔离到“未提交读”状态-但这不能保证所有同一行用户都将获得新号码(可能是最差的)

3rd option: 第三种选择:

Heard something about TABLOCK but have no idea whether could be considered in this situation. 听说过有关TABLOCK的信息,但不知道是否可以在这种情况下考虑。

...something else? ...还有吗?

At the moment I am considering to use 1st option -catch error and inform users. 目前,我正在考虑使用第一个选项-catch错误并通知用户。

I followed some of your older questions... This is obviously not so easy to solve. 我遵循了您的一些较旧的问题...这显然不是那么容易解决。 Therefore I have a completely different idea: 因此,我有一个完全不同的想法:

As your ProductNumber is a VARCHAR you could write there whatever you want? 由于您的ProductNumber是VARCHAR您可以在其中编写任何内容?

Would it work to set a GETDATE() as string-literal (ISO 8601) into this column on insert and execute an UPDATE statement later, which will re-set the value to the correct numbering according to the order of insertion? 在插入时在此列中将GETDATE()设置为字符串文字(ISO 8601),然后在以后执行UPDATE语句将根据插入顺序将值重新设置为正确的编号,是否可行?

Strange and ugly anyway... 反正又丑陋...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM