In this blog post I would like to explain a new feature released in Sitefinity 8.2 that allows older Sitefinity assemblies to attempt to run on a newer (upgraded) database. As you may know, upgrading Sitefinity in a load balancing environment without downtime and data loss requires quite a complicated deployment setup in order to pull it off. While avoiding downtime is more easily achievable, data loss prevention is the more sensitive and harder to achieve goal. I am not going to go into details about how to achieve such setups, I would like to introduce a handy new feature that will improve the success rate of both of the goals mentioned above, especially when it comes to avoiding downtime.
At its current state, Sitefinity assemblies’ version must be greater or equal to the database schema version. When they are equal, the application is in a stable state. Otherwise, the database is upgraded to version of the assemblies, thus achieving the stable state. Now if by any chance you try to run older assemblies on a newer database that would result in a Yellow Screen of Death screaming: Downgrade is not allowed! To get a better idea of this behavior, see the chart below.
Database |
Assemblies |
Result |
1.0 |
1.0 |
App is running as usual |
1.0 |
2.0 |
Assemblies Upgrade Database to 2.0 |
2.0 |
1.0 |
Yellow screen: Downgrade not allowed |
Throwing this exception is meant to warn you that a downgrade is not allowed and to prevent your web application from starting. Sitefinity can, in fact, start under these conditions but it might be unstable. Notice the word might in the previous sentence. The stability of the application in such a case would depend on the amount and nature of the database changes between the two versions. On a lucky day, the newer database model would have breaking changes in, let's say, the Events but not in the News. For example, if on your homepage you are displaying News, the page will load without problems. If, however, it has Events widget, it will throw an exception related to the change. We can all agree that throwing exceptions is not something you want on your production website. At least not most of the time.
There is one scenario, however, where you might want to give this unstable state a try. For instance, imagine a website in a load balanced environment that has two Sitefinity instances connected to one common database and you need to do an upgrade to a newer version. In order to avoid downtime during the upgrade, which is the point of the load-balanced setup in the first place, you would want to upgrade the instances one by one. However, when you upgrade the first instance, the second one will start throwing the downgrade exception because at that point its assemblies' versions are lower than the database schema version. To reiterate, if this is an upgrade where the breaking database changes do not affect your most visited pages, you might want to give this old instance a shot. This type of scenario is why we introduced the IgnoreDowngradeExceptions setting. By default the warning is set to false, but if you want to set it to true you will need to add it as an attribute to the connection string.
Example:
<
add
name
=
"Sitefinity"
connectionString
=
"data source=.;Integrated Security=SSPI;initial catalog=SitefinityDb"
ignoreDowngradeExceptions
=
"true"
providerName
=
"System.Data.SqlClient"
/>
Please be aware that if your configurations are not stored in the files system, but in the database, you can enable this feature by adding SF_ignoreDowngradeException=true directly in the connection string:
<
add
name
=
"Sitefinity"
connectionString
=
"data source=.;Integrated Security=SSPI;initial catalog=SitefinityDb;SF_ignoreDowngradeExceptions=true"
providerName
=
"System.Data.SqlClient"
/>
Such lucky days might be less probable on a major-version upgrade, but would be very probable when upgrading to hotfixes or internal builds. These releases usually contain bug fixes in the code and, very rarely, changes in the database model. Such release is the top candidate for taking advantage of this option.
Remember, the load-balanced communication between the two instances should be interrupted in order to prevent the upgrading instance to restart the old instance while performing the changes. How and why this communication between instances happens is out of the scope of this blog post, but as I said, it is important it is stopped. It can be stopped by removing the configured instances in the System config, under the load balancing section. So in a nutshell, you need to stop the communication between the instances in the System config, and to set ignoreDowngradeExceptions flag of the connection string to true. See the documentation for more details.
However, before you get all excited, there is one final thing to consider. We released this feature with Sitefinity 8.2, but it is meant to be used on the older version in the upgrade process, i.e. the version which you are upgrading from should be at least 8.2. That means you can take advantage of the benefits of this feature when you upgrade to the first internal build after 8.2 or on the next major release.
Give it a try and tell me what you think in the comments below.