Archive for February, 2010

Deadlocks are a property of SQL Server’s pessimistic concurrency scheme

I’ve encountered more than a few SQL Server based applications where deadlocks are treated as an error in almost exactly the same manner as say, a .NET null-reference exception. In most cases this means the user sees a message along the lines of: “An error has occurred, please try again”.

A deadlock is usually a recoverable condition, so this is the wrong behaviour, at least at first. Any concurrency scheme where a “thread” is able to block waiting on a lock while holding other lock(s) is potentially subject to deadlock conditions. Deadlocks and pessimistic concurrency go hand-in-hand.

More often than not a simple retry of the rolled-back transaction will succeed. An error should be allowed to bubble-up to the user only after a specified number of retries; three retries is often reasonable.

This does not mean to say that you shouldn’t endeavour to limit deadlocks in your SQL Server applications, of course you should. Rolling-back and retrying a transaction is an expensive operation that you want to avoid if at all possible but the point is, don’t give up after the first attempt.

Comments off

Using JSONP for cross-host "Ajax" calls with jQuery

When trying to make cross-host Ajax calls, you’ll likely run foul of the browser’s “same origin policy”. Usually, the user will be presented with a pop-up similar to this:

This page is accessing information that is not under its control.

One solution is JSONP. It happens that the same origin policy is relaxed for certain tags and that includes the <script> tag. JSONP takes advantage of this by writing a <script> tag to the document (instead of using the XMLHttpRequest object of traditional Ajax). The src attribute of the script tag specifies the Ajax URL. Instead of the traditional HTML response, the server returns JavaScript; more specifically, a JSON object wrapped in a function call. In many implementations, the JSON simply encapsulates a HTML fragment and the called function loads it somewhere in the document.

Obviously, due to the nature of JSONP, POST requests are not available.

jQuery makes implementing the client-side of JSONP straightforward through the ajax() method. Here’s an example (assume “host1” is hosting the page and “host2” is serving Ajax requests):

$.ajax({
  url: ‘http://host2/GetJSON’,
  dataType: ‘jsonp’,
  success: function(data) {
    $(‘#content’).html(data.html);
  }
});

jQuery will append a call-back method name to the query-string of the URL: http://host2/GetJSON?callback=jsonp1265718231899

It is the responsibility of the server-side code to output JavaScript that calls the method supplied in the query-string. So, given the above request, host2 would return JavaScript that looks like this:

jsonp1265718231899({ html: "<h1>HTML Fragment</h1>" });

The JSON object ({ html: "<h1>HTML Fragment</h1>" }) is passed to the success call-back. In this particular example the success call-back simply updates the document with the value of the html property.

jQuery is a powerful JavaScript library with all kinds of useful functionality in addition to Ajax support. If you haven’t tried it already, I recommend you do. You won’t look back.

Comments off

Copying the contents of a hard disk drive and an opportunity to revisit Linux

My current 80GB HDD was running low on disk space and so it was time for an upgrade. My plan was to copy the data from the old HDD to a new 500GB one and extend the one and only system partition. A straightforward task.

Now, the PC in question has only one SATA port on the motherboard so that ruled out a straight disk-to-disk copy, complicating things slightly. I decided to copy the existing data to a Windows fileserver on my local network, install the new disk and copy it back. Using an external USB hard disk would’ve been a viable alternative.

I don’t know how to do a straight sector copy in Windows without resorting to third-party software or writing code, so I decided this would be a good opportunity to try a Linux-based “Live CD”. I chose Ubuntu simply because it was the first that came to mind and I knew it would have almost all the utilities that I needed right there on the CD.

First impressions… everything just works. Booting from the Ubuntu CD, after a minute or so I’m looking at the GNOME desktop. Wireless networking is working; video is working; impressive!

To mount the SMB share on my Win fileserver, I needed to grab smbfs …

sudo apt-get install smbfs

… and mount the share:

smbmount \\\\myserver\\myshare ./images –o user=myuser

I piped the existing HDD data through gzip to save on storage and network bandwidth:

sudo dd if=/dev/sda bs=512 | gzip > ./images/sda.img.gz

After a few hours of network copying, I swapped out the old HDD for the new and copied the data back:

gzip –c -d ./images/sda.img.gz | sudo dd of=/dev/sda bs=512

Note: I copied every sector including the MBR / partition table from the old to the new disk. This approach will only work if both disks have the same geometries.

dd responds to the USR1 signal by writing status to stderr, so I tracked progress (updating every 2 minutes) during long running dd operations using:

sudo watch –n 120 killall –s USR1 dd

I then used GParted to take care of resizing the NTFS partition to occupy the entire disk.

After a reboot into Win XP and one chkdsk later, I had more than 400GB free disk space.

Disclaimer: I don’t recommend you follow this approach unless you’ve backed up your data, are prepared for the possibility that things may turn bad and have a reasonable idea of what you’re doing.

Comments off

Tree traversal, LINQ style

When dealing with tree structures, it’s helpful to be able to visit all nodes. Here’s an extension method that makes traversing tree structures easier (in this case, in preorder, depth-first).

internal static class TreeTraverse
{
    public static IEnumerable<T> PreorderTraverse<T>(this T node, Func<T, IEnumerable<T>> childrenFor)
    {
        yield return node;

        var childNodes = childrenFor(node);
        if (childNodes != null)
        {
            foreach (var childNode in childNodes.SelectMany(n => n.PreorderTraverse(childrenFor)))
            {
                yield return childNode;
            }
        }
    }
}

This extension method allows you to treat any type as the root node of a tree, providing you can define a sensible childrenFor method for it.

Example usage:

var root = new Node
{
    Name = "root",
    Children = new List<Node>()
    {
        new Node
        {
            Name = "root > child A",
            Children = new List<Node>()
            {
                new Node
                {
                    Name = "root > child A > child AA"
                }
            }
        },
        new Node
        {
            Name = "root > child B"
        }
    }
};

foreach (var node in root.PreorderTraverse(n => n.Children))
{
    Console.WriteLine(node.Name);
}

Where Node is defined as:

class Node
{
    public string Name { get; set; }
    public IEnumerable<Node> Children { get; set; }
}

To use PreorderTraverse on an IEnumerable<T> you can combine with SelectMany, as in fact the PreorderTraverse extension method does.

Comments off

Unknown PCI device (Device Manager) – How can I find out what drivers I need?

If a PCI device is showing up as an “Unknown Device” in the Windows Device Manager (devmgmt.msc) and you’re not sure what the manufacturer and/or device name is, here’s a quick tip that may help.

Pull up the Properties for the device. Select “Hardware Ids” in the drop-down and make a note of the Vendor (VEN_XXXX) and Device (DEV_XXXX) identifiers (in this example, 8086 and 24C6). With this information you can search for your device at http://www.pcidatabase.com/.

DeviceProperties 

Once you have the vendor and device name, it will increase your chances of finding the correct driver on the manufacturer’s website.

Comments off

« Previous entries Next Page » Next Page »