SharePoint Dragons

Nikander & Margriet on SharePoint

Revisiting the System.Transactions resource manager for SharePoint

And: Is Google really better than Bing?

Written by: Margriet Bruggeman, Nikander Bruggeman.

16 September, 2011

Heads up, a slight warning, the technical good stuff comes later, we’ll start indulging ourselves with a little “amuse cerveau” (amusement for the brain, if you’ve never heard of the term that’s okay, we just mixed two French words together).

We’ve been writing blog posts about SharePoint for years now, and the most popular one we’ve ever written was “Exploring the Data View Web Part”, currently located on our new web site at http://www.loisandclark.eu/Pages/dvwp.aspx . This apparently was and still is a popular topic among SharePoint aficionado’s and it helps that this particular blog post turns up high in search results.

Let’s see what Google does when searching for “data view web part”:

image

It’s the first spot, no surprise there because this blog post is a brilliant piece of literature! Please note, http://www.lcbridge.nl was our old web site, we’re not using it anymore. Now let’s see what happens if we execute the same search query with Bing:

image

Aha, if you forget the advertising, you’ll agree that our blog post shows up as the fourth result. Therefore, our temporary scientifically proven conclusion is that Google is 4 times better than Bing, we’ll see later if it stays that way.

We have written other blog posts that we consider to have been very successful because they gained us new customers offering interesting projects. An example of such a blog post is “Velocity: Solving a Spider-Man/Human Torch dilemma”, currently located at http://www.loisandclark.eu/Pages/Velocity.aspx . Being free contractors, such posts are kind of a big thing and they certainly don’t happen all of the time.

Then there are (luckily a few) blog posts that backfired in unexpected ways. In “Fast Search Server 2010 for SharePoint: brief discussion”, currently located at http://www.loisandclark.eu/Pages/FastSearch.aspx , we talked briefly about SharePoint Search and the acquisition of Microsoft of Fast. Soon after it’s publication on May 1st 2010 we started seeing referrer URLs in our web logs leading to http://arnoldit.com/wordpress/2010/05/03/fast-search-server-2010-vision/ . Being curious, we read it and it was not exactly the kind of fan mail we were hoping for. Don’t you think it’s just nicer when people just get along? Anyway, if we ever get to rural Kentucky, we’ll make sure to find that Arnold geezer in his high-tech nerve center and give him a good kicking! As a side note, we have high hopes that the blog post we’re writing now might be a potential candidate for a bit of unexpected backfiring too.

And then there is the blog post that we’re revisiting today, “Building a System.Transactions resource manager for SharePoint”, currently located at http://www.loisandclark.eu/Pages/transactions.aspx . This blog post explains how to build transaction support into SharePoint for list items. Being 100% serious, this is hands down and by far the best thing currently written about that specific topic. However, this blog post has two problems. The first one is that almost no one bothers to read it!

Why is that? There’s nothing wrong with it’s visibility. Look, if you go to Google and search for “sharepoint transactions” it shows up as the first result (still pointing to lcbridge.nl, a web site we’ll be discontinuing in a couple months).

image

If you Bing it something terrible happens. It’s the first result, but of the 3rd page! Is this a terrible injustice? We were wondering, so we went ahead and opened the first result. This is what we saw:

Question: “Programmtically i am Using List Webservice to Update the Document Meta data once document get uploaded.I want to implement Transaction in this such that if any exception then rollback it.”

Answer: “This question has come up before and the answer has been neither WSS nor MOSS provide any transactional support via the standard object model or web services.  Someone may know different, but I think you will need to roll your own.”

So, we put in the time and effort and write an 11,000+ words article (for comparison, a large MSDN article is up to 4000 words) that discusses exactly how to build transactional support using the standard SharePoint object model into SharePoint, and Bing thinks that that is less relevant than this little Q & A? We can go ahead and discuss the other results listed ahead of our poor neglected blog post, but the results would be very similar and our sadness would increasingly increase. Oh boy, if we ever come to Seattle again we’ll make sure to go to the Microsoft campus, find the Bing team in their high-tech nerve center and give them too a good kicking!

This brings us to two conclusions:

  1. Although we absolutely love Microsoft technology and recommend it to people whenever we can (did you know the Windows 8 pre-beta was released two days ago?), it pains us to say that we do feel that Google is better for searching than Bing.
  2. Transaction support for SharePoint list items is an esoteric topic that nobody is really interested in and that’s probably why Microsoft hasn’t bothered to build it in yet.

Strangely enough, conclusion two doesn’t stop us from writing about transactions in SharePoint again.

We said earlier that “Building a System.Transactions resource manager for SharePoint” had a second problem, and that’s the reason we’re revisiting this topic today. If you made it this far, it’s probably a good idea to browse through the original article at http://www.loisandclark.eu/Pages/transactions.aspx , otherwise the rest of this blog post won’t make much sense.

Our code worked great within a console application or service, but not within a web context. Usage resulted in invalidated SPRequests. Because of that, we propose an altered version that does support a web context. The most interesting change is in the Rollback method. The durable file manager then looks something like this:

  public class DurableFileManager : VolatileMossResourceManager, IEnlistmentNotification
  {

    private SPFile _objFile;

    public SPFile File
    {
      get { return _objFile; }
      set { _objFile = value; }
    }

    public Guid FileId { get; set; }

    public Guid SiteId { get; set; }

    public Guid WebId { get; set; }

    public void CheckIn(string strComment)
    {
      File.CheckIn(strComment);
    }

    public void CheckOut()
    {
      File.CheckOut();
    }

    public override void Rollback(Enlistment enlistment)
    {
      using (SPSite objSite = new SPSite(SiteId))
      {
        objSite.AllowUnsafeUpdates = true;

        using (SPWeb objWeb = objSite.OpenWeb(WebId))
        {
          objWeb.AllowUnsafeUpdates = true;

          SPFile objFile = objWeb.GetFile(FileId);

          if (objFile.CheckOutStatus == SPFile.SPCheckOutStatus.None)
          {
            objFile.CheckOut();
          }

          foreach (string strKey in UndoLog.Keys)
          {
            objFile.Properties[strKey] = UndoLog[strKey];
          }

          objFile.Update();
          objFile.CheckIn(“rollback because of a failed transaction”);

          objWeb.AllowUnsafeUpdates = false;
        }

        objSite.AllowUnsafeUpdates = false;
      }

      enlistment.Done();
    }

    public void SetValue(string strKey, string strValue)
    {
      EnlistTransaction();
      SaveOrgValue(strKey, File.Properties[strKey].ToString());
           
      File.Item.Properties[strKey] = strValue;
    }

    public void Update()
    {     
      File.Item.UpdateOverwriteVersion();
    }

    public DurableFileManager(SPFile objFile)
    {
      File = objFile;
      FileId = objFile.UniqueId;
      WebId = objFile.Item.Web.ID;
      SiteId = objFile.Item.Web.Site.ID;
    }
  }

The volatile file manager looks something like this (again, the most interesting change is in the Rollback method):

  public class FileManager : VolatileMossResourceManager, IEnlistmentNotification
  {
    public void CheckIn(string strComment)
    {
      File.CheckIn(strComment);
    }

    public void CheckOut()
    {
      File.CheckOut();
    }

    public override void Commit(Enlistment enlistment)
    {
      //CheckIn(“System.Transaction manager commits transaction”);
      enlistment.Done();
    }

    public Guid SiteId { get; set; }
    public Guid WebId { get; set; }
    public Guid FileId { get; set; }

    public override void Rollback(Enlistment enlistment)
    {
      using (SPSite objSite = new SPSite(SiteId))
      {
        objSite.AllowUnsafeUpdates = true;

        using (SPWeb objWeb = objSite.OpenWeb(WebId))
        {
          objWeb.AllowUnsafeUpdates = true;

           SPFile objFile = objWeb.GetFile(FileId);

           if (objFile.CheckOutStatus == SPFile.SPCheckOutStatus.None)
           {
             objFile.CheckOut();
           }

           foreach (string strKey in UndoLog.Keys)
           {
             objFile.Properties[strKey] = UndoLog[strKey];
           }

           objFile.Update();
           objFile.CheckIn(“rollback because of a failed transaction”);

           objWeb.AllowUnsafeUpdates = false;
        }

        objSite.AllowUnsafeUpdates = false;
      }
      enlistment.Done();
    }

    public void SetValue(string strKey, string strValue)
    {
      EnlistTransaction();
      SaveOrgValue(strKey, File.Properties[strKey].ToString());
      File.Item.Properties[strKey] = strValue;
      File.Item.UpdateOverwriteVersion();

    }

    public void Update()
    {
    }
    private void LockFile()
    {
      if (!MetadataIsDirty)
      {
        if (File.CheckOutStatus != SPFile.SPCheckOutStatus.None) throw new Exception(“Can’t lock file”);
        File.CheckOut();
        MetadataIsDirty = true;
        LockedFile = true;
      }
    }

    public FileManager(SPFile objFile)
    {
      File = objFile;
      FileId = objFile.UniqueId;
      WebId = objFile.Item.Web.ID;
      SiteId = objFile.Item.Web.Site.ID;
    }

    private SPFile _objFile;
    public SPFile File
    {
      get
      {
        return _objFile;
      }
      set
      {
        _objFile = value;
      }
    }

    private bool _blnLockedFile;
    public bool LockedFile
    {
      get { return _blnLockedFile; }
      set { _blnLockedFile = value; }
    }
  }

That’s all folks!

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 395 other followers

%d bloggers like this: