- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
concurrency problem?
Joined: 06-Nov-2007
Hi,
I have the following issue with these 2 tables.
create table "RaceGameResult" ( "ID" bigint not null, "StartTime" datetime not null, "EndTime" datetime not null, "Players" smallint not null, "TournamentID" bigint null, "GameSettingID" bigint not null, "GameAccountID" bigint null, "Status" smallint default 0 not null, "UpdateUserID" uniqueidentifier not null, "UpdateTimeStamp" datetime default getdate() not null, "UpdateKey" bigint default 1 not null) ON 'PRIMARY'
alter table "RaceGameResult" add constraint "PK_GameResult" primary key clustered ("ID")
create table "RaceGamePlayerResult" ( "GameResultID" bigint not null, "UserID" bigint not null, "FinishTime" int not null, "FinishPosition" smallint not null, "StakeAmount" decimal(14,2) not null, "WinAmount" decimal(14,2) not null, "PlayerIP" nvarchar(22) not null, "Status" smallint default 0 not null, "UpdateUserID" uniqueidentifier not null, "UpdateTimeStamp" datetime default getdate() not null, "UpdateKey" bigint default 1 not null) ON 'PRIMARY'
alter table "RaceGamePlayerResult" add constraint "PK_GamePlayerResult" primary key clustered ("GameResultID", "UserID")
I have a multithreaded application which stores game results. We have generated the entities RaceGameResultEntity raceGameResultEntity and RaceGamePlayerResultEntity raceGamePlayerResultEntity.
If saving is done through 1 thread, everything runs fine. If I use 2 and more threads for saving game results at the same time, from time to time this happens:
Worker_2 calls: bool saved = raceGameResultEntity.Save(true) [Id='196', IsDirty='True', IsNew='True'.] Worker_1 calls: bool saved = raceGameResultEntity.Save(true) [Id='194', IsDirty='True', IsNew='True'.]
Worker_1 gets exceptions: Message: 'An exception was caught during the execution of an action query: Violation of PRIMARY KEY constraint 'PK_GamePlayerResult'. Cannot insert duplicate key in object 'carrace.RaceGamePlayerResult'. The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.',
InnerEx='Violation of PRIMARY KEY constraint 'PK_GamePlayerResult'. Cannot insert duplicate key in object 'carrace.RaceGamePlayerResult'. The statement has been terminated.',
QueryExec: ' Query: INSERT INTO [Gamas].[carrace].[RaceGamePlayerResult] ([GameResultID], [UserID], [FinishTime], [FinishPosition], [StakeAmount], [WinAmount], [PlayerIP], [Status], [UpdateUserID], [UpdateTimeStamp], [UpdateKey]) VALUES (@GameResultId, @UserId, @FinishTime, @FinishPosition, @StakeAmount, @WinAmount, @PlayerIp, @Status, @UpdateUserId, @UpdateTimeStamp, @UpdateKey) Parameter: @GameResultId : Int64. Length: 0. Precision: 19. Scale: 0. Direction: Input. Value: 196. Parameter: @UserId : Int64. Length: 0. Precision: 19. Scale: 0. Direction: Input. Value: 211. Parameter: @FinishTime : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 243200. Parameter: @FinishPosition : Int16. Length: 0. Precision: 5. Scale: 0. Direction: Input. Value: 1. Parameter: @StakeAmount : Decimal. Length: 0. Precision: 14. Scale: 2. Direction: Input. Value: 3.00. Parameter: @WinAmount : Decimal. Length: 0. Precision: 14. Scale: 2. Direction: Input. Value: 0. Parameter: @PlayerIp : String. Length: 22. Precision: 0. Scale: 0. Direction: Input. Value: "127.0.0.1:33826". Parameter: @Status : Int16. Length: 0. Precision: 5. Scale: 0. Direction: Input. Value: 0. Parameter: @UpdateUserId : Guid. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 00000000-0000-0000-0000-000000000000. Parameter: @UpdateTimeStamp : DateTime. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 4/11/2008 8:44:17 AM. Parameter: @UpdateKey : Int64. Length: 0. Precision: 19. Scale: 0. Direction: Input. Value: 1.
Worker_2 gets saved==false, as a return value of raceGameResultEntity.Save(true)
What can I do to handle this concurrency? For concurreny implementations we designed all our tables with these 3 columns: UpdateUserID, UpdateTimeStamp and UpdateKey.
Thanks for any advices!
We use LLBLGenPro v2.5 final.
Regards, Tino
Worker_2 calls: bool saved = raceGameResultEntity.Save(true) [Id='196', IsDirty='True', IsNew='True'.] Worker_1 calls: bool saved = raceGameResultEntity.Save(true) [Id='194', IsDirty='True', IsNew='True'.]
I don't know how come the above inserts cause a PK violation although they have different Ids to insert.
Also concurrency management is used for updating and deleting but would have no reason to be used when inserting.
I'd recommend starting with the database profiler to examine the generated queries and their order of execution.
Worker_2 gets saved==false, as a return value of raceGameResultEntity.Save(true)
Would you please use the profiler to post the executed query of the second thread.