Thursday, January 31, 2019

WCF : Tuning WCF Service Performance and Default value for Throttling Settings

This blog will discuss how to tune WCF service performance under heavy load and explain the throttling settings.

Here is default value for each throttling setting as per msdn (wcf4.5 and higher version)


Default Value
Single core -processor
MaxConcurrentCalls
16 * No of processor
16
MaxConcurrentInstances
MaxConcurrentCalls + MaxConcurrentInstances
116
MaxConcurrentSessions
100 * No of processor
100

In WCF , service throttling settings control the WCF service performance and server resource unitization, without knowing if you provide the highest value (INT MAX) to these setting, then service will be completed chocked.



We can achieve balance performance of service and controller resource usages by using following settings
  • MaxConcurrentCalls: specify maximum number of message concurrently process by Service Host.
  • MaxConcurrentInstances: specify the maximum number of instance object of service.
  • MaxConcurrentSessions : specify the maximum number of sessions a ServiceHost object can accept
Web.config:

<serviceBehaviors>
        <behavior name="serviceBehavior">
          <serviceThrottling 
            maxConcurrentCalls="16"
             maxConcurrentInstances="116"
             maxConcurrentSessions ="100"
           />
         <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>


Thanks for visiting!!

Swagger UI Disable Swagger document

In this blog, we will discuss how to disable the swagger so that user can only view the API document and not able to submit any request through Swagger UI.



Here is swagger document for Order API:




You can see, here Try it Out! Button is available and user can submit the request and get Order Information by order number.

If you are API in Production or any other sensitive environment and don’t want to user to allow to submit any kind of request [GET/POST/Put] but still you want to publish the API documentation.

There is a SupportedSubmitMethods(new string[] {}) method in swagger configuration class, that will be allowed to disabled “Try it Out” button.

C#:

public class SwaggerConfig

    {
        public static void Register()
        {
            var thisAssembly = typeof(SwaggerConfig).Assembly;

            GlobalConfiguration.Configuration
                .EnableSwagger(c =>
                    {                      
                        c.SingleApiVersion("v1", "Order API Documentation");                     
                     
                    })
                .EnableSwaggerUi(c =>
                    {                      
                       c.SupportedSubmitMethods(new string[] {  });                      
                    });
        }
    }


after change, there is no ‘Try It Out’ button available but rest of API information is still available.


Other option is also available example you want hide ‘Try It Out” button for all HTTP verbs like  POST, HEAD, PUT but it should be available  for GET only

  c.SupportedSubmitMethods(new string[] { "Get" });

Other swagger related posts

Monday, January 28, 2019

WCF Exception: “The service operation requires a transaction to be flowed”

WCF Exception: “The service operation requires a transaction to be flowed”
Recently I encountered the wcf transaction error while calling to WCF service and this WCF service is transaction based service and I tried to call service without any transaction scope.

try
            {
                Account.AccountServiceClient account = new Account.AccountServiceClient();
                account.UpdateTaxRefundAmount(taxId, refund);
            }

                   
              catch (Exception ex)
            {
                throw;
            }   


In this blog, we will discuss how to create transaction scope and call transaction enabled service method.



You can use TranscationScope class to define a block of code which will be executed in a transaction and this call expose below methods to manage the current transaction status:
  •  Complete() – all operations within the current transaction scope are completed successfully.
  •   Dispose () – it aborts the current transaction.

Example C# : 
        
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                try
                {
                    // Call service method
                Account.AccountServiceClient account = new Account.AccountServiceClient();
                account.UpdateTaxRefundAmount(taxId, refund);

                    ts.Complete();
                }
                catch (Exception ex)
                {
                    ts.Dispose();
                }
             }

you can define the behavior of truncation scope by passing the below transcationScopeOption to constructor of transcationScope class 
  • Required - a transaction is required by the scope, if there is already an existing transaction scope otherwise it creates new transaction.
  • RequiredNew – it always create a new transaction.
  • Surpress – it suppress the parent transaction or surrounding transaction.

Friday, January 25, 2019

SQLBulkCopy : Received an invalid column length from the bcp client for colid 10

SQLBulkCopy: Received an invalid column length from the bcp client for colid 10.

I recently encountered this exception while migrating data from old system to new system. I used SQLBulkCopy ddl to bulk copy of data and here is C# Code

C#:

void BulkInsert<TEntity> (IEnumerable items, string schemaName, bool keepIdentity = truewhere TEntity : class
        {
            var context = new DBEntities() { AuditChanges = false };

            context.Database.Connection.Open();

            var conn = context.Database.Connection;

            var options = SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.CheckConstraints;

            if (!keepIdentity)
            {
                options = SqlBulkCopyOptions.CheckConstraints;
            }

            using (var scope = conn.BeginTransaction(IsolationLevel.ReadCommitted))
            {
                var copy = new SqlBulkCopy(conn as SqlConnection, options, scope as SqlTransaction)
                {
                 
                    BatchSize = 20000,               
                    DestinationTableName = schemaName + $".{typeof(TEntity).Name}",
                };

                var dbReader = items.AsDataReader();              
                copy.WriteToServer(dbReader);
                scope.Commit();
            }
         }

I looked into data and destination table schema and found that there are few record in source table, which length is exceeded to destination table's column.

So to resolve this issue, I simple increased the length of destination table column from varchar (10) to varchar (20).

Below SQL Script increase size of varchar column 10 to 20
         
 ALTER TABLE [dbo].[TableName] ALTER COLUMN [ColumnName] Varchar(20)


Thanks for visiting!!

Tuesday, January 22, 2019

SQL - how to create temporal table in SQL Server

In SQL Server 2016, Microsoft introduced a new feature Temporal Table. By using this feature, we can easily keep the full history of data change for table without doing any extra coding or efforts. It will allow to you get table data at any point of time of past.

Temporal table have same number of fields as Regular/Main tables and have two new extra columns start and end date.
1. If you update a record in main table, the old version of record will be added into history table with start and current end date stamp.
2. If you delete a record from main table, the deleted record will be added into history table with start and current end date stamp.

Temporal table serves many purposes:
Audit: temporal table is being used to store the data history of main table and you can retrieve the old version of data on given specific date time.
Back-up: temporal table helps you to restore the accidentally deleted or updated record. 
Syntax to Create Temporal Table:
 There are many options available to create temporal table.
 1. Auto-generated name: you can create a temporal table without specify schema and table name and system create the corresponding history table with auto-generated name.


CREATE TABLE Office  
(   
  OfficeID int NOT NULL PRIMARY KEY CLUSTERED
   , OfficeName varchar(50) NOT NULL
   , Street   varchar(50) NOT NULL
   , City varchar(50) NOT NULL
   , State varchar(2) NOT NULL
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL
   , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)    
)   

WITH (SYSTEM_VERSIONING = ON)  



temporal history table



2. User defined name: you can create a temporal table with use defined schema and table name.

CREATE TABLE Office  
(   
  OfficeID int NOT NULL PRIMARY KEY CLUSTERED
   , OfficeName varchar(50) NOT NULL
   , Street   varchar(50) NOT NULL
   , City varchar(50) NOT NULL
   , State varchar(2) NOT NULL
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL
   , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)    
)  
WITH   
   (  
      SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.OfficeHistory)  
   )


system-versioned Table




Insert new record in Office table : 

Insert dbo.office(officeID, OfficeName, Street, City, State)
Select 1, 'NYK', '1001 Street RD', 'NYK', 'OH'


Select * from dbo.office

temporal table

SELECT *  FROM [dbo].[OfficeHistory] 


temporal history table

No Record available in history table

Update Office Street Address:

Update dbo.office SET Street = '1999 PTS Street' where OfficeName = 'NYK'


Select * from dbo.office

system-versioned Table

SELECT *  FROM [dbo].[OfficeHistory]

temporal history table

You can see old version of office record in history table with start and end time stamp.

 Delete Office Street Address:

  Delete from dbo.office where OfficeName = 'NYK'

  SELECT *  FROM dbo.office

  No Record available in office table


  SELECT *  FROM [dbo].[OfficeHistory]


temporal history table

In history table, you can see two old version of record for same office (office id – 1)


Other related blogs:

SQL : How to truncate system version table ( temporal table)

SQL Server - Identify unused indexes

 In this blog, we learn about the index usage information (SYS.DM_DB_INDEX_USAGE_STATS) and analyze the index usage data (USER_SEEKS, USER_S...