Base solution for your next web application
Open Closed

Background worker MARS error #11895


User avatar
0
alliance225 created

Hello, I am trying to use the default ABP background worker.

In my controller i have call my job; await _updateSalesDomaineService.TriggerStatsVentesMoisJob((int)PeriodeId);

Here is my Job:


using Abp.BackgroundJobs;
using Abp.Domain.Services;
using System.Threading.Tasks;

namespace DocuPro.DomainServices
{
	public class UpdateSalesDomaineService : DomainService, IDomainService
	{
		private readonly IBackgroundJobManager _backgroundJobManager;

		public UpdateSalesDomaineService(IBackgroundJobManager backgroundJobManager)
		{
			_backgroundJobManager = backgroundJobManager;
		}

		public async Task TriggerStatsVentesMoisJob(int periodeId)
		{

			Logger.Warn("UpdateStatsVentesMoisJob. Job STARTED");

			await _backgroundJobManager.EnqueueAsync<UpdateStatsVentesMoisJob, StatsVentesMoisJobArgs>(new StatsVentesMoisJobArgs
			{
				PeriodeId = periodeId
			});

			Logger.Warn("UpdateStatsVentesMoisJob. Job ENDED");

		}

		// Other domain service methods...
	}

	public class StatsVentesMoisJobArgs
	{
		public int PeriodeId { get; set; }
	}
}

And here is my method:

using Abp.BackgroundJobs;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using DocuPro.CommonBases;
using DocuPro.SortiesLocalesBases;
using System;
using System.Threading.Tasks;

namespace DocuPro.DomainServices
{
	public class UpdateStatsVentesMoisJob : BackgroundJob<StatsVentesMoisJobArgs>, ITransientDependency
	{
		private readonly ISortiesLocalesesAppService _sortiesLocalesesAppService;
		private readonly IRepository<Periode> _periodeRepository;

		public UpdateStatsVentesMoisJob(
			ISortiesLocalesesAppService sortiesLocalesesAppService,
			IRepository<Periode> periodeRepository)
		{
			_sortiesLocalesesAppService = sortiesLocalesesAppService;
			_periodeRepository = periodeRepository;
		}

		[UnitOfWork]
		public override void Execute(StatsVentesMoisJobArgs args)
		{
			Logger.Warn("UpdateStatsVentesMoisJob. Job STARTED.");
			var periodeId = args.PeriodeId;
			if (periodeId <= 0)
			{
				Logger.Warn("Invalid PeriodeId provided to UpdateStatsVentesMoisJob. Job aborted.");
				return;
			}

			try
			{
				_sortiesLocalesesAppService.UpdateStatsVentesMois(periodeId);
			}
			catch (Exception ex)
			{
				Logger.Error($"An error occurred while executing UpdateStatsVentesMoisJob for PeriodeId {periodeId}.", ex);
			}
		}
	}
}

Here is my UpdateStatsVentesMois method:

   public async Task UpdateStatsVentesMois(int periodeId)
   {

	Logger.Warn("UpdateStatsVentesMoisJob. Job STARTED. UpdateStatsVentesMois");

	var statsList = await GetStatsVentesMois(periodeId); // Assuming this returns a list of VentesMoisStatsDto

       await _statsVentesRepository.DeleteAllByPeriodeId(periodeId);

	Logger.Warn($"UpdateStatsVentesMoisJob. NOMBRE MOIS. DELETED ");

	foreach (var stat in statsList)
       {
       
       

           // Insert new record
           var newStat = new CreateOrEditStatsVenteDto
           {
               Pays = stat.Pays,
               Grossiste = stat.Grossiste,
               GrossisteId= stat.GrossisteId,
               ProduitLibelle = stat.ProduitLibelle,
               Ventes = (int)stat.Ventes,
               VentesMois = (int)stat.VentesMois,
               Poids = stat.Poids,
               VentesMoisMMinus1 = (int)stat.VentesMoisMMinus1,
               TauxEvol = stat.TauxEvol,
               BudgetMois = stat.BudgetMois,
               TauxReal = stat.TauxReal,
               BudgetAnnee = stat.BudgetAnnee,
               TauxRealCumulBudget = stat.TauxRealCumulBudget,
               AvgVentesLast3Months = (int)stat.AvgVentesLast3Months,
               AvgVentesLast6Months = (int)stat.AvgVentesLast6Months,
               AvgVentesLast12Months = (int)stat.AvgVentesLast12Months,
               CAMois = (int)stat.CAMois,
               CAMoisMMinus1 = (int)stat.CAMoisMMinus1,
               TauxEvolCA = stat.TauxEvolCA,
               BudgetMoisCA = (int)stat.BudgetMoisCA,
               TauxRealCA = stat.TauxRealCA,
               BudgetAnneeCA = (int)stat.BudgetAnneeCA,
               CumulCA = (int)stat.CumulCA,
               CumulBudgetCA = (int)stat.CumulBudgetCA,
               TauxRealCumulBudgetCA = stat.TauxRealCumulBudgetCA,
               PGHT = stat.PGHT,
               SortieLocalesId = stat.SortieLocalesId, // Assuming this is the correct property name
               PeriodeId = stat.PeriodeId,
           };

         await  _statsVentesRepository.CreateOrEdit(newStat);
          
       }

	Logger.Warn($"UpdateStatsVentesMoisJob. FIN ");

}
    

On this : var statsList = await GetStatsVentesMois(periodeId);

I get an error : System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The transaction operation cannot be performed because there are pending requests working on this transaction. at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject

I have set MultipleActiveResultSets=true;

I am sending you my application, database and Log by email


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    As I can see, your AppService method is async but the background job is sync. I suggest you 2 changes;

    1. Change your background job to inherit from AsyncBackgroundJob instead of BackgroundJob
    2. Use a domain service instead of using SortiesLocalesesAppService in your background job.
  • User Avatar
    0
    alliance225 created

    Hello, thanks for your help.

    I changed the job signature to this:

    public class UpdateStatsVentesMoisJob : AsyncBackgroundJob<StatsVentesMoisJobArgs>, ITransientDependency

    Then I created this under DocuPro.Application/DomainServices

    using Abp.Domain.Repositories; using DocuPro.CommonBases; using Microsoft.Extensions.Logging; using Stripe; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

    namespace DocuPro.DomainServices { public class DomaineServiceDatabaseFunctions: IDomaineServiceDatabaseFunctions {

    	private readonly IRepository&lt;Periode&gt; _periodeRepository;
    	private readonly ILogger&lt;DomaineServiceDatabaseFunctions&gt; _logger;
    	
    
    	public DomaineServiceDatabaseFunctions(IRepository&lt;Periode&gt; periodeRepository, ILogger&lt;DomaineServiceDatabaseFunctions&gt; logger)
    	{
    		_periodeRepository = periodeRepository;
    		_logger = logger;
    	}
    
    	public async Task UpdateStatsVentesMois(int periodeId)
    	{
    		var periode = await _periodeRepository.GetAsync(periodeId);
    		if (periode == null)
    		{
    			_logger.LogWarning($"UpdateStatsVentesMois. Periode with Id {periodeId} not found.");
    			return;
    		}
    
    		_logger.LogInformation($"UpdateStatsVentesMois. Periode with Id {periodeId} WAS found.");
    
    		// Other logic...
    	}
    }
    

    }

    But when I execute I get:

    WARN 2024-03-04 12:10:33,578 [38 ] .DomainServices.UpdateStatsVentesMoisJob - UpdateStatsVentesMoisJob. Job STARTED. ERROR 2024-03-04 12:10:33,756 [43 ] .DomainServices.UpdateStatsVentesMoisJob - An error occurred while executing UpdateStatsVentesMoisJob for PeriodeId 146. Abp.Domain.Entities.EntityNotFoundException: There is no such an entity. Entity type: DocuPro.CommonBases.Periode, id: 146 at Abp.Domain.Repositories.AbpRepositoryBase`2.GetAsync(TPrimaryKey id) at DocuPro.DomainServices.DomaineServiceDatabaseFunctions.UpdateStatsVentesMois(Int32 periodeId) in C:\Apps\MedicPro Fevrier\MedicPro.All\src\DocuPro.Application\DomainServices\DomaineServiceDatabaseFunctions.cs:line 28

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Is this entity DocuPro.CommonBases.Periode, id: 146 belongs to a tenant or host ? If it belongs to a tenant, you need to switch to tenant context, see https://aspnetboilerplate.com/Pages/Documents/Multi-Tenancy#switching-between-host-and-tenants