I have been running an application and have just looked at the error log it produces. I am getting multiple errors for primary key violations. Having looked at the source code that performs the action I cannot understand why this is occurring.
The application is written in C# on Dotnet Core and does not use an ORM framework instead it uses SqlObjects
.
The command updates the table using a DbCommand
transaction. AS I said I am getting a Primary Key violation even though the command itself removes the entry before resubmitting with an updated time. I cannot seem to understand why this is the case especially when SqlCommand is supposed to be a transaction.
Command
_sqlObjectFactory.GetConnection()
.Using(connection =>
{
var command = connection.Command(
_sqlObjectFactory, "DELETE FROM pf_ServiceHeartbeat WHERE ServiceName = @ServiceName AND MachineName = @MachineName")
.AddParameter(_sqlObjectFactory, "@ServiceName", serviceName)
.AddParameter(_sqlObjectFactory, "@MachineName", machineName);
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO pf_ServiceHeartbeat (ServiceName, MachineName, LastRun) VALUES (@ServiceName, @MachineName, @LastRun)";
command.AddParameter(_sqlObjectFactory, "@LastRun", lastRun);
command.ExecuteNonQuery();
});
Error Log
Error: 11/07/2017 12:50:20 - SqlException: Violation of PRIMARY KEY constraint 'PK_pf_ServiceHeartbeat'. Cannot insert duplicate key in object 'dbo.pf_ServiceHeartbeat'. The duplicate key value is (PopForums.Email.EmailApplicationService, MACHINENAME).
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at PopForums.Data.Sql.Repositories.ServiceHeartbeatRepository.<>c__DisplayClass3_0.b__0(DbConnection connection) in E:\Projects\Forum\src\PopForums.Sql\Repositories\ServiceHeartbeatRepository.cs:line 40
at PopForums.Data.Sql.Extensions.Using(DbConnection connection, Action`1 action) in E:\Projects\Forum\src\PopForums.Sql\Extensions.cs:line 53
at PopForums.Data.Sql.Repositories.ServiceHeartbeatRepository.RecordHeartbeat1(String serviceName, String machineName, DateTime lastRun) in E:\Projects\Forum\src\PopForums.Sql\Repositories\ServiceHeartbeatRepository.cs:line 32
at PopForums.Services.ServiceHeartbeatService.Add(String serviceName, String machineName) in E:\Projects\Forum\src\PopForums\Services\ServiceHeartbeatService.cs:line 37
at PopForums.Services.ServiceHeartbeatService.RecordHeartbeat(String serviceName, String machineName) in E:\Projects\Forum\src\PopForums\Services\ServiceHeartbeatService.cs:line 25
at PopForums.Services.ApplicationServiceBase.Execute(Object sender) in E:\Projects\Forum\src\PopForums\Services\ApplicationServiceBase.cs:line 50
HelpLink.ProdName: Microsoft SQL Server
HelpLink.ProdVer: 13.00.4422
HelpLink.EvtSrc: MSSQLServer
HelpLink.EvtID: 2627
HelpLink.BaseHelpUrl: http://go.microsoft.com/fwlink
HelpLink.LinkId: 20476
Updated
Below is the definition of the serviceHeartbeat table
CREATE TABLE [dbo].[pf_ServiceHeartbeat](
[ServiceName] [nvarchar](256) NOT NULL,
[MachineName] [nvarchar](256) NOT NULL,
[LastRun] [datetime] NOT NULL,
CONSTRAINT [PK_pf_ServiceHeartbeat] PRIMARY KEY CLUSTERED
(
[ServiceName] ASC,
[MachineName] ASC
)
)