public static TReturnType TryWriteToDatabase <TParam1, TParam2, TParam3, TParam4, TParam5, TReturnType>(Func <TParam1, TParam2, TParam3, TParam4, TParam5, TReturnType> dataFunc,
                                                                                                         TParam1 parameter1,
                                                                                                         TParam2 parameter2,
                                                                                                         TParam3 parameter3,
                                                                                                         TParam4 parameter4,
                                                                                                         TParam5 parameter5,
                                                                                                         int numOfAttempts)
 {
     try
     {
         if (numOfAttempts > MAX_PROCESSING_ATTEMPTS_ON_CHANGE_CONFLICT_EXCEPTION)
         {
             using (TransactionScope transactionScope = TransactionScopeInitialiser.GetNewDefaultTransactionScope())
             {
                 TReturnType result = dataFunc(parameter1, parameter2, parameter3, parameter4, parameter5);
                 transactionScope.Complete();
                 return(result);
             }
         }
         else
         {
             return(dataFunc(parameter1, parameter2, parameter3, parameter4, parameter5));
         }
     }
     catch (Exception ex)
     {
         if ((ex is SqlException ||
              //ex is ChangeConflictException ||
              ex is TransactionAbortedException) &&
             numOfAttempts < MAX_PROCESSING_ATTEMPTS_ON_ANY_EXCEPTION)
         {
             numOfAttempts++;
             LogExceptionAsWarning(ex, numOfAttempts);
             Thread.Sleep(WAIT_TIME_ON_CHANGE_CONFLICT_EXCEPTION_IN_MILISECONDS + GetRandomInterval());
             return(TryWriteToDatabase <TParam1, TParam2, TParam3, TParam4, TParam5, TReturnType>(dataFunc, parameter1, parameter2, parameter3, parameter4, parameter5, numOfAttempts));
         }
         else
         {
             string errorMessage = string.Format(FAILED_PERMANENTLY_MESSAGE_FORMAT, MAX_PROCESSING_ATTEMPTS_ON_ANY_EXCEPTION);
             _logger.Error(ex, errorMessage);
             throw;
         }
     }
 }
 public static void TryWriteToDatabase <TParam1>(Action <TParam1> dataAction,
                                                 TParam1 parameter1,
                                                 int numOfAttempts)
 {
     try
     {
         if (numOfAttempts > MAX_PROCESSING_ATTEMPTS_ON_CHANGE_CONFLICT_EXCEPTION)
         {
             using (TransactionScope transactionScope = TransactionScopeInitialiser.GetNewDefaultTransactionScope())
             {
                 dataAction(parameter1);
                 transactionScope.Complete();
             }
         }
         else
         {
             dataAction(parameter1);
         }
     }
     catch (Exception ex)
     {
         if ((ex is SqlException ||
              // ex is ChangeConflictException ||
              ex is TransactionAbortedException) &&
             numOfAttempts < MAX_PROCESSING_ATTEMPTS_ON_ANY_EXCEPTION)
         {
             numOfAttempts++;
             LogExceptionAsWarning(ex, numOfAttempts);
             Thread.Sleep(WAIT_TIME_ON_CHANGE_CONFLICT_EXCEPTION_IN_MILISECONDS + GetRandomInterval());
             TryWriteToDatabase <TParam1>(dataAction, parameter1, numOfAttempts);
         }
         else
         {
             string errorMessage = string.Format(FAILED_PERMANENTLY_MESSAGE_FORMAT, MAX_PROCESSING_ATTEMPTS_ON_ANY_EXCEPTION);
             _logger.Error(ex, errorMessage);
             throw;
         }
     }
 }