![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Using Adaptive Server Anywhere 9.0.2.3668. I have a system that has multiple connections to the database that all update records in the database. When a record is updated, a trigger is fired which then retrieves a sequence number from a Sequence number table. After retrieving the sequence number the Sequence Number Table is updated and it increments to the next one. (Also performs min/max checks on the sequence number). The issue that I am running into is that every so often I have two transactions that are picking up the same sequence number. I can see in the transaction log that the first connection grabs the current value, and then increments it. In the second connection I see that the same value was retrieved as the first value, but the increment never occurs. I am thinking that I do not see it in the log because when it went to update, the value was already incremented by the first connection. What can I do to prevent a situation like this from occuring? I am a bit nervous to use a lock of some sort because these transactions are from a system that is real-time and any kind of long delay could have really bad results. I am familiar with mutexing in code, but is there a way to mutex this record somehow? Thanks in advance. |
#3
| |||
| |||
|
|
We came across this with key pool implementations sometimes. My trick there was to not fetch the value first but do an update first ... and do that within a nested transaction level (see savepoint/release savepoint). A user defined function may be best for this. Alternatively, one could utilize the get_identity( ) system function if an autoincrement is being used for this. hth "Paul" wrote in message news:4b2915c4.34bb.1681692777 (AT) sybase (DOT) com... Using Adaptive Server Anywhere 9.0.2.3668. I have a system that has multiple connections to the database that all update records in the database. When a record is updated, a trigger is fired which then retrieves a sequence number from a Sequence number table. After retrieving the sequence number the Sequence Number Table is updated and it increments to the next one. (Also performs min/max checks on the sequence number). The issue that I am running into is that every so often I have two transactions that are picking up the same sequence number. I can see in the transaction log that the first connection grabs the current value, and then increments it. In the second connection I see that the same value was retrieved as the first value, but the increment never occurs. I am thinking that I do not see it in the log because when it went to update, the value was already incremented by the first connection. What can I do to prevent a situation like this from occuring? I am a bit nervous to use a lock of some sort because these transactions are from a system that is real-time and any kind of long delay could have really bad results. I am familiar with mutexing in code, but is there a way to mutex this record somehow? Thanks in advance. |
#4
| |||
| |||
|
|
Thanks for the response. I already have a function that is being used. This is below: CREATE FUNCTION "accusort"."fGetNextNSequenceID"(szHost varchar(64)) RETURNS bigint DETERMINISTIC BEGIN DECLARE "nReturnSequenceNumber" bigint; DECLARE nReturnValue bigint; DECLARE err_notfound EXCEPTION FOR SQLSTATE '02000'; DECLARE nContinue smallint; DECLARE nSequenceNumber bigint; DECLARE nMinSequenceNumber bigint; DECLARE nMaxSequenceNumber bigint; SELECT CurrentSequenceNumber, MinSequenceNumber, MaxSequenceNumber into nSequenceNumber, nMinSequenceNumber, nMaxSequenceNumber FROM accusort.HostInformation WHERE HostName = szHost; If SQLState = err_notfound Then set nContinue = 0; set nReturnValue = 0; ELSE set nContinue = 1; set nReturnValue = 0; end if; IF nContinue = 1 THEN set nReturnSequenceNumber = nSequenceNumber; If nSequenceNumber >= nMaxSequenceNumber then set nSequenceNumber = nMinSequenceNumber; else set nSequenceNumber = nSequenceNumber + 1; end if; update accusort.HostInformation set CurrentSequenceNumber = nSequenceNumber WHERE HostName = szHost; END IF; RETURN "nReturnSequenceNumber"; END; My table structure is as follows: CREATE TABLE "accusort"."HostInformation" ( "HostName" varchar(64) NOT NULL, "CurrentState" varchar(64) NOT NULL, "CurrentSequenceNumber" bigint NOT NULL, "MinSequenceNumber" bigint NULL, "MaxSequenceNumber" bigint NULL, PRIMARY KEY ( "HostName" ) ); If I wanted to use the get_identity call, how do I need to setup my table then so that the autoincrementing field would only go as high as my max value, and then reset to my min? Thanks in advance. We came across this with key pool implementations sometimes. My trick there was to not fetch the value first but do an update first ... and do that within a nested transaction level (see savepoint/release savepoint). A user defined function may be best for this. Alternatively, one could utilize the get_identity( ) system function if an autoincrement is being used for this. hth "Paul" wrote in message news:4b2915c4.34bb.1681692777 (AT) sybase (DOT) com... Using Adaptive Server Anywhere 9.0.2.3668. I have a system that has multiple connections to the database that all update records in the database. When a record is updated, a trigger is fired which then retrieves a sequence number from a Sequence number table. After retrieving the sequence number the Sequence Number Table is updated and it increments to the next one. (Also performs min/max checks on the sequence number). The issue that I am running into is that every so often I have two transactions that are picking up the same sequence number. I can see in the transaction log that the first connection grabs the current value, and then increments it. In the second connection I see that the same value was retrieved as the first value, but the increment never occurs. I am thinking that I do not see it in the log because when it went to update, the value was already incremented by the first connection. What can I do to prevent a situation like this from occuring? I am a bit nervous to use a lock of some sort because these transactions are from a system that is real-time and any kind of long delay could have really bad results. I am familiar with mutexing in code, but is there a way to mutex this record somehow? Thanks in advance. |
#5
| |||
| |||
|
|
DETERMINISTIC NOT DETERMINISTIC |
#6
| |||
| |||
|
|
SELECT CurrentSequenceNumber, MinSequenceNumber, MaxSequenceNumber into nSequenceNumber, nMinSequenceNumber, nMaxSequenceNumber FROM accusort.HostInformation WHERE HostName = szHost; |
|
Thanks for the response. I already have a function that is being used. This is below: CREATE FUNCTION "accusort"."fGetNextNSequenceID"(szHost varchar(64)) RETURNS bigint DETERMINISTIC BEGIN DECLARE "nReturnSequenceNumber" bigint; DECLARE nReturnValue bigint; DECLARE err_notfound EXCEPTION FOR SQLSTATE '02000'; DECLARE nContinue smallint; DECLARE nSequenceNumber bigint; DECLARE nMinSequenceNumber bigint; DECLARE nMaxSequenceNumber bigint; SELECT CurrentSequenceNumber, MinSequenceNumber, MaxSequenceNumber into nSequenceNumber, nMinSequenceNumber, nMaxSequenceNumber FROM accusort.HostInformation WHERE HostName = szHost; If SQLState = err_notfound Then set nContinue = 0; set nReturnValue = 0; ELSE set nContinue = 1; set nReturnValue = 0; end if; IF nContinue = 1 THEN set nReturnSequenceNumber = nSequenceNumber; If nSequenceNumber >= nMaxSequenceNumber then set nSequenceNumber = nMinSequenceNumber; else set nSequenceNumber = nSequenceNumber + 1; end if; update accusort.HostInformation set CurrentSequenceNumber = nSequenceNumber WHERE HostName = szHost; END IF; RETURN "nReturnSequenceNumber"; END; My table structure is as follows: CREATE TABLE "accusort"."HostInformation" ( "HostName" varchar(64) NOT NULL, "CurrentState" varchar(64) NOT NULL, "CurrentSequenceNumber" bigint NOT NULL, "MinSequenceNumber" bigint NULL, "MaxSequenceNumber" bigint NULL, PRIMARY KEY ( "HostName" ) ); If I wanted to use the get_identity call, how do I need to setup my table then so that the autoincrementing field would only go as high as my max value, and then reset to my min? Thanks in advance. We came across this with key pool implementations sometimes. My trick there was to not fetch the value first but do an update first ... and do that within a nested transaction level (see savepoint/release savepoint). A user defined function may be best for this. Alternatively, one could utilize the get_identity( ) system function if an autoincrement is being used for this. hth "Paul" wrote in message news:4b2915c4.34bb.1681692777 (AT) sybase (DOT) com... Using Adaptive Server Anywhere 9.0.2.3668. I have a system that has multiple connections to the database that all update records in the database. When a record is updated, a trigger is fired which then retrieves a sequence number from a Sequence number table. After retrieving the sequence number the Sequence Number Table is updated and it increments to the next one. (Also performs min/max checks on the sequence number). The issue that I am running into is that every so often I have two transactions that are picking up the same sequence number. I can see in the transaction log that the first connection grabs the current value, and then increments it. In the second connection I see that the same value was retrieved as the first value, but the increment never occurs. I am thinking that I do not see it in the log because when it went to update, the value was already incremented by the first connection. What can I do to prevent a situation like this from occuring? I am a bit nervous to use a lock of some sort because these transactions are from a system that is real-time and any kind of long delay could have really bad results. I am familiar with mutexing in code, but is there a way to mutex this record somehow? Thanks in advance. |
![]() |
| Thread Tools | |
| Display Modes | |
| |