Thursday, 22 May 2014

Minimising deadlocks with READ_COMMITTED_SNAPSHOT

The problem

We have a system that has a number of separate Windows services that all access a shared database hosted by SQL Server 2008 R2. The system is used to provide online hydraulic modelling in support of a water utility company’s maintenance activities. The services are built around SynerGEE Water, a hydraulic modelling product from DNVGL.

One of the Windows services is responsible for monitoring a model library – SynerGEE models are stored as MDB files on the file system – and when a new or updated model is detected it adds a MODEL record to the database. It also indexes all of the pipes in the model and adds them to a MODEL_PIPE table in the database.

A second service checks the database for new MODEL records and then invokes SynerGEE to perform some hydraulic analysis. The results of this analysis are used to update the MODEL_PIPE records.

We observed that if a number of models had been updated in one go the result was that sometimes a database deadlock occurred when the second service was querying the MODEL_PIPE table. This was because the first service was in the process of adding other MODEL_PIPE records for other models at the same time.

We are using NHibernate for all data access and all database queries or updates are wrapped in transactions with the assistance of the Spring.Net transaction template. NHibernate Profiler was used to confirm that all the transactions were correctly formed and we could see that the transactions were using the READ COMMITTED isolation level.

The solution

Firstly, I did some research around Minimizing Deadlocks and noted that using a row-based isolation level can help. In particular, activating READ_COMMITTED_SNAPSHOT on the database can help by allowing SQL Server to use row versioning rather than shared locks.

“When the READ_COMMITTED_SNAPSHOT database option is set ON, a transaction running under read committed isolation level uses row versioning rather than shared locks during read operations.” [1]

Further research around snapshot isolation levels provided further insight:

“The READ_COMMITTED_SNAPSHOT database option determines the behavior of the default READ COMMITTED isolation level when snapshot isolation is enabled in a database. If you do not explicitly specify READ_COMMITTED_SNAPSHOT ON, READ COMMITTED is applied to all implicit transactions. This produces the same behavior as setting READ_COMMITTED_SNAPSHOT OFF (the default). When READ_COMMITTED_SNAPSHOT OFF is in effect, the Database Engine uses shared locks to enforce the default isolation level. If you set the READ_COMMITTED_SNAPSHOT database option to ON, the database engine uses row versioning and snapshot isolation as the default, instead of using locks to protect the data.” [2]

Bingo! If the READ_COMMITTED_SNAPSHOT database option is set to ON row versioning is used instead of locks.

“Once snapshot isolation is enabled, updated row versions for each transaction are maintained in tempdb. A unique transaction sequence number identifies each transaction, and these unique numbers are recorded for each row version. The transaction works with the most recent row versions having a sequence number before the sequence number of the transaction. Newer row versions created after the transaction has begun are ignored by the transaction…

…Snapshot isolation uses an optimistic concurrency model. If a snapshot transaction attempts to commit modifications to data that has changed since the transaction began, the transaction will roll back and an error will be raised. ” [2]

In our case this looked very interesting because the first Windows service adds new MODEL and MODEL_PIPE records in a transaction and is done with them. The second Windows service then reads the new MODEL and MODEL_PIPE records and updates them in a separate transaction. The chances of an optimistic concurrency issue are minimal. Although the two services are accessing the same table they are not accessing the same rows. Therefore, using row version-based locks would allow the two services to work better together.

So, I enabled READ_COMMITTED_SNAPSHOT on the database [3] and found that the deadlocks no longer occurred.

ALTER DATABASE <dbname> SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE <dbname> SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE <dbname> SET MULTI_USER;

Result!

References

[1] Minimizing Deadlocks, Technet.

[2] Snapshot Isolation in SQL Server, MSDN.

[3] Enabling Row Versioning-Based Isolation Levels, Technet.

Monday, 21 April 2014

BitDefender subscription update (2)

OK, an hour or two after submitting the email to BitDefender in step 9 of my previous post I received a reply saying my automatic renewal for BitDefender Internet Security 2014 has been cancelled. Praise be!

BitDefender, if you are listening, please change the way you manage automatic renewals of your product. Allow users to cancel their subscription or automatic renewal from the product page as easily as they can renew them. You are operating in a sector that requires the trust of your users. Engender that trust by making the process honest and transparent. I think your business will benefit from it. 

Sunday, 20 April 2014

BitDefender subscription update

OK, here’s an update to the situation regarding my BitDefender subscriptions (see previous post Are BitDefender (Avangate/Digital River) behaving like confidence tricksters?).

I had a couple of emails waiting for me this morning. There has been some movement, but not on everything.

Step 8 - Subscription cancellation (huzzah!)

BitDefender have cancelled my “BitDefender Internet Security 2013 subscription”. Thank you BitDefender. Thank goodness for that.

However, I note that they have not cancelled the automatic renewal of the BitDefender Internet Security 2014 subscription so I’m going to have to do that separately again. I’m going to use the email address I was given on Twitter (see below).

Step 9 - Twitter power

Well, yesterday I popped an update on Twitter and it looks like BitDefender heard me. I’m now going to contact them using the email address they provided (bitsy@bitdefender.com) to get the automatic renewal of the 2014 subscription cancelled. Let’s see what happens then.

bd21
bd22

Saturday, 19 April 2014

Are BitDefender (Avangate/Digital River) behaving like confidence tricksters?


I have been a user of BitDefender by Digital River for a few years now. In January of this year I ‘upgraded’ my BitDefender installation to BitDefender Internet Security 2014 subscription. I was surprised to find that today – 19th April 2014 – I was charged £40.46 GBP because my subscription had been renewed automatically.

I don’t want auto-renewal of anything and I couldn’t understand why I was being charged again with 281 days left on my subscription.

What I discovered is that the subscriptions for the old versions of the product are still in place and are being automatically renewed and I can’t cancel them!

This seems to be a trend amongst the anti-virus vendors. I had a similar experience with Kaspersky. These are companies that are operating in an environment where you are inclined to trust them. After all, they are working to protect you, aren’t they? What they are actually doing is making you accidentally sign up for automatic renewals (there was probably some small print and an inconspicuous checkbox on their payment page) and then not letting you cancel the subscription or making it very hard to do so.

This post is a description of all the steps I’ve taken to try and cancel the automatic renewal. At this point all attempts have failed but I’ll update this post if I succeed. Please read on and make your own minds up as to whether BitDefender are behaving like confidence tricksters.

Suffice is to say, I would advise anybody to avoid BitDefender like the plague.
  

Step 1 – Do some checks

OK, so BitDefender shows me that I have 281 days left.

bd1

So, lets hop over to their website and see what gives. I log on to my account and head over to the product page and this is what I see:

bd2

Looks like all my previous products are still active. I don’t use them anymore because I’ve upgraded to the 2014 version so how can I cancel the automatic renewals? Well, not on this page and there are no instructions here either.

Isn’t it reasonable to expect to see a button allowing you to cancel a subscription? After all they are very keen for you to renew. Even a little link next to each subscription would be a help. 
 

Step 2 – Check the email

The automatic renewal email I received from BitDefender had some instruction about how to follow up:

bd3 
 

Step 3 – Find my order

So I head over to www.findmyorder.com to see what gives. The site requires an order number and a password. Luckily the email from BitDefender included an order number so a put it in along with my account password:

bd4

What? Incorrect order number and/or password?

OK, lets try the ‘forget your password link’ to see if it’s the password. This gives me a form asking for the order number again. No problem, I enter the order number, click Submit and it sends me an email.

bd5

The weird thing is the password is completely different to my account password (by the way, I strongly suspect everyone is getting the same password back for this page). Never mind, maybe it’s me. Let’s enter the password and see what happens:

bd7

Great, we can manage a subscription. Let’s click the link…

Step 4 – Manage subscription (not)

Ah, another login.

bd8

Never mind. Let’s try logging in.

bd9

Now take my word for it, it doesn’t matter what password I use (my BitDefender password or the one they sent me in the email previously) I get the same thing: “Enter a valid email address”.

It could be that it’s bad validation but by now I’m getting suspicious.

Step 5 – Contact support

So, back on the product page from step 1 I use the Support link and get this dialog:

bd10

OK, where’s the 2014 product (I have a 2014 subscription listed on the product page)? And take my word for it clicking “the full list of products” link doesn’t list it either. Oh well, let’s use the 2013 version for now and see what gives.

bd11

I click FIND HELP and get a useful looking result:

bd12

Let’s click the link:

bd13

Oh good, another link. OK, here goes:

bd14

What you get is a nice form to fill in. The problem is, there’s no 2014 version of the subscription listed but the automatic renewal I want to cancel is listed as BitDefender Internet Security 2014, not 2013.

Anyway, I have submitted this form a number of times, once for each ‘version’ I have asking for automatic renewals of my subscriptions to be stopped. I have also submitted an extra one listing all 3 of the products I own asking the same.

Now I don’t know where this form goes but I haven’t even received an automated response and as far as I can see nothing has happened.

But really, why do I have to go through all these pages to try – and fail – to cancel a subscription or an automatic renewal when all subscriptions are listed on my product page? Why oh why can’t I do it there? Why should I have to contact support for this?

Anyway, this hasn’t worked so what can I do now?

Step 6 – eHow makes a suggestion

Getting desperate I do a Google search with Bing and find a link to an eHow page that suggests going to http://shop.BitDefender.com and completing some simple steps. Now the steps aren’t right; it looks like the article is out of date. So, I ended up clicking Contact Us at the top of the page and then SUPPORT but that gets you right back to the support page from step 5. Bummer.

However, if you click “My BitDefender” at the top of the page you get something that looks quite useful:

bd15

But yet again there are no ways to cancel subscriptions or automatic renewals.

But look, there’s a support link at the top of the page, I wonder where that goes:

bd16

Well, it goes nowhere. You stay on the same page.

Step 7 – The mystery page

OK, now I can’t remember how I found this page. It looks like the page that the eHow article was suggesting in Step 6 but I can’t remember how I found it.

Anyway, I completed the form but it absolutely will not submit it because it tells me that no orders were found! Now remember this is using the order number I was given in BitDefender’s automatic renewal email. Funny that. The same order number worked in step 3.

You really do have to question if any of this is accidental.

bd17 

Step 8 – Email customer support directly

Well, on the mystery page in Step 7 there was an email address listed (customerservice@bitdefender.com). So, I sent an email to that address.

bd18

OK, guess what came back. Now remember this was an email address taken from a publically accessible page on the BitDefender web site.

bd19

What a surprise.


Thursday, 17 April 2014

Modifying layout and formatting rules in ReSharper

We use StyleCop to implement some of our coding standards. Although in the main we use StyleCop defaults there are a few exceptions for which we have created custom rules. I found that some of ReSharper’s formatting and layout rules clash with our StyleCop rules.

What follows is a description of how I set about changing a couple of those ReSharper formatting and layout rules.

Using directives before namespaces


There may be arguments for putting using directives inside the namespace but our standards – and my preference - require they appear at the top of the file. I’m not alone in this.

By default when ReSharper helps out by adding using directives for you it adds them inside the namespace. To make ReSharper follow this convention I did this:
  1. In Visual Studio go to ReSharper > Options.
  2. Navigate to Code Editing > C# > Namespace Imports.
  3. Deselect “Add using directives to the deepest scope”.
  4. Save the changes.



Private instance fields prefixed with an underscore


To add an underscore to private instance fields do the following:
  1. In Visual Studio go to ReSharper > Options.
  2. Navigate to Code Editing > C# > Naming Style.
  3. Double-click on “Instance Fields (private).
  4. Add a Name Prefix and click Set.
  5. Save the changes.

   


Don't use 'this' qualifier for instance members

 

To prevent ReSharper from including "this." for instance members:

  1. In Visual Studio go to ReSharper > Options.
  2. Navigate to Code Editing > C# > Formatting Style > Other.
  3. Scroll down to "Force "this." qualifier for instance member" and select "Do not use" from the dropdown list.
  4. Save the changes.




Monday, 3 March 2014

Validation adorners not displaying in WPF

The problem

I was developing a WPF application using the IDataErrorInfo interface to perform validation on view models. When errors were encountered I wanted them to be displayed in the UI using adorners to change border appearances and to show error messages. I also wanted these adorners to show when the form first loaded so the user could see straight away what fields needed to be completed.

The problem was that the adorners only appeared after the user changed the values of the validated controls. When the form first loaded things like required fields were not adorned.


Figure 1 – No adorners showing on required fields etc. when the form first loaded.



Figure 2 – The desired result with adorners displayed correctly.

After spending some time checking the behaviour of the application I could see that IDataErrorInfo members were being called when the form loaded and that INotifyPropertyChanged was correctly implemented and the property changed event was being raised correctly.

The solution

The solution was to wrap the form elements in an AdornerDecorator. So, where I previously had a Grid element containing the rows of input controls and labels I wrapped that grid in an AdornerDecorator.

<StackPanel Orientation="Vertical">
    <AdornerDecorator>
        <Grid>
            <Grid.RowDefinitions>
                <!-- Row definitions omitted -->
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <!-- Column definitions omitted -->
            </Grid.ColumnDefinitions>

            <!-- Input controls and labels omitted -->
            
        </Grid>
    </AdornerDecorator>
    
    <!-- Other layout omitted -->
    
</StackPanel>

Explanation

The controls displaying validation errors in the application were based on styles that used the Validation.ErrorTemplate to provide adorned layout to use in the case of errors. For adorners to be displayed there needs to be an AdornerLayer available in the visual tree.

“An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements.” [1]

There will be times when there isn’t an AdornerLayer available so you may have to provide one. The way to do this is to add an AdornerDecorator to your XAML remembering that somewhere there will be a call to the static AdornerLayer.GetAdornerLayer method which walks the visual tree looking for an AdornerLayer.

“This static method traverses up the visual tree starting at the specified Visual and returns the first adorner layer found.” [2]
“The AdornerDecorator specifies the position of the AdornerLayer in the visual tree. It is typically used in a ControlTemplate for a control that might host Adorner objects. For example, the ControlTemplate of a Window contains an AdornerDecorator so that the child elements of the window can be adorned. The GetAdornerLayer method returns null if you pass in an element that does not have an AdornerDecorator as an ancestor in its visual tree.” [3]

Note that - as stated above - the AdornerDecorator is typically used in a ControlTemplate. You might want to explore this avenue further.

References

[1] Adorners Overview
[2] AdornerLayer.GetAdornerLayer Method
[3] AdornerDecorator Class

Saturday, 1 March 2014

Create a self-signed certificate for development in IIS 7

This post is a quick follow up to an earlier one, Generating temp SSL certificates for development, which showed a manual method for creating self-signed certificates. If you’ve got IIS 7 then the following method is much quicker and easier.

The method

Open the Internet Information Services (IIS) Manager.

Select the server node in the connections pane.

server-cert-001

Find the Sever Certificates item and double-click on it.

Right-click in the Server Certificates pane and choose Create Self-Signed Certificate… from the pop-up menu.

server-cert-002

In the dialog box provide a friendly name for the certificate and click OK.

 server-cert-003

That’s all there is to creating a self-signed certificate in IIS 7!

To use the certificate on a web site hosted in IIS you need to open the Sites node in the Connected Sites pane and select the web site that needs the SSL certificate.

In the Actions pane on the right click Bindings…

server-cert-004

If there isn’t an HTTPS binding you’ll have to add one in the Site Bindings dialog. You could edit an existing HTTPS binding if you need to.

server-cert-005

You’ll be prompted to select an SSL certificate for the binding. Just select the self-signed certificate you’ve created. Click OK and you’re done.

server-cert-006

You are now ready to use SSL on your website.

References