TransactionScope and Serializable

When using transaction scopes and SQL connections I recently tripped over a undesirable effect. By default when creating a new transaction scope the connection is raised to serializable. I can see the logic in this, as it provides the safest starting point and allows the developer to change the behaviour after careful consideration.

A quick explanation of serializable isolation level : Transactions occur isolated and sequential. However this is just an illusion and other transactions maybe running alongside but only if the database can maintain the façade of running in an isolated manner.

I first noticed the issue when monitoring the connection pool, there were many connections that had an isolation level above what I expected, it turns out that once the isolation level was raised by enlisting in the transaction scope the isolation was not being set back to read committed.

To work around this you need to Execute “SET TRANSACTION ISOLATION LEVEL” on the connection before releasing, or turn off connection pooling (Which I wouldn’t recommend without a very good reason, establishing a database connection is an expensive operation).

WIF and load balancing with MVC 3.

Recently I’ve been getting to grips with WIF and the starter STS which I must say is an excellent starting point. A requirement for a project that I’ve been working on was to enable the site to run in a load balanced environment without any affinity to a particular node.

From the outset this seemed quite straight forward. After customizing the STS to use our own credential store and aligning the machine keys things looked to be rocking, well from an STS point of view.

After adding the STS reference and deploying the web application everything looked OK initially, looking in firebug I could see plenty of requests reporting “500” internal server error.

After much investigation it became clear that one of the nodes couldn’t access the token due to it being protected via DPAPI.

The following assumes that you have a serverCertificate inside the microsoft.identitymodel node in your config. It also assumes that you application pool has access to find the certificate in the local store.

Changes to the global.asax file.

New event handler

void onServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
{
List<CookieTransform> sessionTransforms = new List<CookieTransform>(new CookieTransform[]
{
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate),
new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate)
});

SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
}

Changes to application start method.

protected void Application_Start()
{
FederatedAuthentication.ServiceConfigurationCreated += onServiceConfigurationCreated;
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

The preceding enabled tokens to be treated the same on all nodes in the cluster.

.NET 4.0 and the web.config

So one of the big changes with .NET 4 was a radically smaller web.config file.  By moving the shared aspects of the config from application config files to a machine level config significant savings have been made.

But why did this happen? Well in a nutshell .NET 3 and .NET 3.5 were built upon .NET 2.0 framework, and changes to config files at the machine level could have had all kinds of detrimental effects for the end user. So to tackle this the configuration needed was stored at the application level.

.NET 4.0 is a fresh new version of the framework and as such was a clean slate, installed side by side with prior versions, and hence providing the opportunity to shift things around a little.