/// <summary>
        /// Actual taskletstep execution.
        /// </summary>
        /// <param name="stepExecution"></param>
        /// <exception cref="Exception">&nbsp;</exception>
        protected override void DoExecute(StepExecution stepExecution)
        {
            stepExecution.ExecutionContext.Put(TaskletTypeKey, _tasklet.GetType().Name);
            stepExecution.ExecutionContext.Put(StepConstants.StepTypeKey, GetType().Name);

            _stream.Update(stepExecution.ExecutionContext);

            JobRepository.UpdateExecutionContext(stepExecution);
            JobRepository.UpdateExecutionContext(stepExecution.JobExecution);
            // Shared semaphore per step execution, so other step executions can run
            // in parallel without needing the lock
            Semaphore semaphore = CreateSemaphore();

            _stepOperations.Iterate(StepContextRepeatCallback.GetRepeatCallback(stepExecution,
                                                                                (context, chunkContext) =>
            {
                StepExecution lStepExecution = chunkContext.StepContext.StepExecution;
                _interruptionPolicy.CheckInterrupted(lStepExecution);

                ChunkTransactionCallback callback =
                    new ChunkTransactionCallback(chunkContext, semaphore, this);

                RepeatStatus result;

                using (var scope = TransactionScopeManager.CreateScope())
                {
                    TransactionScopeManager.RegisterTransactionSynchronization(scope, callback);
                    try
                    {
                        result = callback.DoInTransaction();
                    }
                    catch (Exception e)
                    {
                        //Log and rethrow
                        Logger.Error(e, "Transaction will be rollbacked because of an unexpected exception.");
                        throw;     // throw to ensure rollback will occur (no complete)
                    }
                    scope.Complete();
                }
                // Release connections since the transaction has ended
                ConnectionUtil.ReleaseConnections();
                Thread.Sleep(stepExecution.DelayConfig);

                _interruptionPolicy.CheckInterrupted(stepExecution);
                return(result);
            }
                                                                                ));
        }
        /// <summary>
        /// @see IChunkProvider#Provide.
        /// </summary>
        /// <param name="contribution"></param>
        /// <returns></returns>
        public Chunk <T> Provide(StepContribution contribution)
        {
            Chunk <T> inputs = new Chunk <T>();

            _repeatOperations.Iterate(context =>
            {
                var item = Read(contribution, inputs);
                if (item == null)
                {
                    inputs.End = true;
                    return(RepeatStatus.Finished);
                }
                inputs.Add(item);
                contribution.IncrementReadCount();
                return(RepeatStatus.Continuable);
            });
            return(inputs);
        }