Author |
Topic |
kpgraci
Yak Posting Veteran
68 Posts |
Posted - 2012-03-06 : 10:40:15
|
I have a table with the next receipt number to be used for printing a cash receipt.nextNo intI want to query the table to return this number, then increment the number, and do it is sich a way that no other process can come in between the query and increment so as to preserve the integrity of the contiguous receipt number sequence.The application is an asp.net website with potentially multiple simultaneous request for the next receipt number.If I craft a single query (which I'm no 100% sure how to do) will this meet my requirements of 'locking out' other users until it is complete?for example something like this:SELECT nextNo FROM Table; Update Table SET nextNo=nextNo+1;guidance welcome :)kpgkpg |
|
X002548
Not Just a Number
15586 Posts |
|
X002548
Not Just a Number
15586 Posts |
|
kpgraci
Yak Posting Veteran
68 Posts |
Posted - 2012-03-06 : 11:29:41
|
No, Im not using SP but I can.I'm not using an identity clumn becuase I have multiple diffeent users each with their own unique nextnothe actual talbe is as follows:custID int (FK)nextNo intthxkpg |
 |
|
X002548
Not Just a Number
15586 Posts |
|
kpgraci
Yak Posting Veteran
68 Posts |
Posted - 2012-03-06 : 11:47:34
|
quote: Originally posted by X002548 you are going to need to figure out how to hold a row lock until AFTER your row is insertedDo you have a unique constraint on that column in the destination table?
No. Different users can have the same nextNo, however unlikly.kpg |
 |
|
X002548
Not Just a Number
15586 Posts |
|
kpgraci
Yak Posting Veteran
68 Posts |
Posted - 2012-03-06 : 12:52:55
|
quote: Originally posted by X002548 so what's the primary key of your data table?ClientID, NextNo?I sure wonder why you would care about a cash receipt number being sequential..sounds like a bad idea...amount being posted for the wrong client..reports forget the client id...Still..it all comes down to locking the rows...And you don't find that this could be a bottle neck?
The table has no PK.My customers want the numbers to be sequential.Bottle neck? Maybe, not sure about the performace implications.I came up with something that seems to work, but I'm not usre how foolproof it is... here's my code. I'm using transactions and the key line is:UPDATE NextNumber SET @Next = LastReceiptNo = LastReceiptNo + 1 WHERE SN=@SNUsing myConnection As New SqlConnection(LoginClass.getConnectionString) myConnection.Open() Dim transaction As SqlTransaction = myConnection.BeginTransaction Dim myCommand As SqlCommand = myConnection.CreateCommand myCommand.Transaction = transaction 'Transaction 1 ////////////////////////////////////////////////////////// sql = "UPDATE NextNumber SET @Next = LastReceiptNo = LastReceiptNo + 1 WHERE SN=@SN" myCommand.CommandText = sql Dim NextNoParam As SqlParameter = myCommand.Parameters.AddWithValue("Next", 0) NextNoParam.Direction = ParameterDirection.Output myCommand.Parameters.AddWithValue("SN", sn) n = myCommand.ExecuteNonQuery() 'returns number of rows affected If n = 1 Then 'Transaction 2 ////////////////////////////////////////////////////////// 'cleanup myCommand.Parameters.Clear() sql = "INSERT INTO Receipts ReceiptNo VALUES @ReceiptNo WHERE SN=@SN SET @ID = SCOPE_IDENTITY()" Dim IDParam As SqlParameter = myCommand.Parameters.AddWithValue("ID", -1) myCommand.Parameters.AddWithValue("SN", sn) myCommand.Parameters.AddWithValue("ReceiptNo", NextNoParam.Value) myCommand.CommandText = sql n = myCommand.ExecuteNonQuery() 'returns number of rows affected If n = 1 Then ret = IDParam.Value & "|" & NextNoParam.Value transaction.Commit() Else transaction.Rollback() End If 'end of Transaction 2 ////////////////////////////////////////////////////////// Else transaction.Rollback() End IfEnd Using kpg |
 |
|
kpgraci
Yak Posting Veteran
68 Posts |
Posted - 2012-03-06 : 13:27:04
|
I take that back, the PK is going to be ClientID in my example.That was an example, in reality it is SN, a 6 character alphanumeric, but it will be unique in this table, so I will make it the PK.I thinkUPDATE NextNumber SET @Next = LastReceiptNo = LastReceiptNo + 1 WHERE SN=@SNshould work for me, no other process will interrupt a sinlge query, I'm thinking.kpg |
 |
|
LoztInSpace
Aged Yak Warrior
940 Posts |
Posted - 2012-03-06 : 22:57:55
|
Brett is right - this is a crap thing to be attempting.You will kill concurrency using this method because you can't pick the next ID until the transaction currently being processed has finished. If your customer wants to live with that constraint then so be it but it won't scale at all.Your next+1 method won't work either if you turn on snapshot isolation (which you should if you want decent performance).Why on earth do you want numbers without gaps? It's a crazy thing to want and generally has no geniune business merit. What would they be doing in a "real" situation? Have only one till? Have one little old lady handing out receipt numbers as customers leave the store? What happens when she spills coffee on the reciept book?Just use an identity and live with the gaps. |
 |
|
|