Laserfiche Workflow logs a "The INSERT statement conflicted with the FOREIGN KEY constraint "search_activity_instance_fk". Error In the Windows Event Log.

November 8, 2013 | KB: 1013357
Workflow Suite 8, Workflow Suite 9

Summary

When under high load, Workflow may log the following error in the Windows Event Log:

    The INSERT statement conflicted with the FOREIGN KEY constraint "search_activity_instance_fk". The conflict occurred in database "SampleWorkflowDatabase", table "dbo.search_instance", column 'search_id'. The statement has been terminated.

Cause

When the SQL server is under high load, a stored procedure may not properly commit the open transaction upon retry. By default, Workflow automatically retries internal SQL queries that time out. The insert_search_instance stored procedure is run as part of certain maintenance features in Workflow. If a query in this stored procedure times out during the initial run (e.g., the SQL Server is under high load), the transaction is not properly committed during the retry. When SQL Server goes through its internal maintenance tasks, the open transaction is aborted and an expected insert is rolled back.

Workaround

Use the following query to modify the insert_search_instance stored procedure to properly commit or rollback the transaction.

ALTER procedure [dbo].[insert_search_instance]
	@instance_id	uniqueidentifier,
	@parent_instance_id uniqueidentifier,
	@workflow_id	int,
	@workflow_version int
as
	begin
		set nocount on
		set transaction isolation level read committed
		declare
			@error int,
			@error_message nvarchar(256),
			@return	smallint,
			@search_id bigint

		begin transaction

		exec @return = get_internal_search_id @instance_id = @instance_id,
			@search_id = @search_id output
		if @search_id is null
			-- Not in db yet, insert
			begin
				declare @start_date datetime 
				set @start_date = GETUTCDATE()
				insert into search_instance (instance_id, parent_instance_id, version, workflow_id)
				values (@instance_id, @parent_instance_id, @workflow_version, @workflow_id)
				select @search_id = SCOPE_IDENTITY(), @error = @@ERROR
				insert into workflow_reporting_log (report_id, instance_id, workflow_id, version, start_time, status)
				values (@search_id, @instance_id, @workflow_id, @workflow_version, @start_date, 4)
				insert into search_status (search_id, start_time, status_time, status, idle_time)
				values (@search_id, @start_date, @start_date, 4, 0)		
			end
		select @search_id as 'search_id'
		
		commit transaction
		return 0

		fail:
		set @search_id = -1
		rollback transaction
		return -1;
end