Question

An app I am working on has to handle lots of ajax requests that needs to update some data on DB.

[Macromedia][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 66) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

For reads, I've already used the WITH (NOLOCK) hint and that prevented a lot of deadlocks on reads.

What can I do to better deal with writes?

CFLock the update code in CF?

Or is there a way to ask SQL Server to lock a Row instead of a Table?

Have anyone tried implementing CQRS? Seems to solve the problem but I am not clear on how to handle:

  1. ID generation (right now it uses Auto Increment on DB)
  2. How to deal with update request fail if server couldn't send the error back to the client right away.

Thanks

Was it helpful?

Solution

Here are my thoughts on this.

From the ColdFusion server side

I do believe that using named <cflock> tags around your ColdFusion code that updates the database could prevent the deadlock issue on the database server. Using a named lock would make each call single threaded. However, you could run into timeouts on the ColdFusion server side, waiting for the <cflock>, if transactions are taking a while. Handling it in this way on the ColdFusion server side may also slow down your application. You could do some load testing before and after to see how this method affects your app.

From the database server side

First of all let me say that I don't think deadlocks on the database server can be entirely prevented, just minimized and handled appropriately. I found this reference on TechNet for you - Minimizing Deadlocks. The first sentence from that page:

Although deadlocks cannot be completely avoided, following certain coding conventions can minimize the chance of generating a deadlock.

Here are the key points from that reference. They go into a bit more detail about each topic so please read the original source.

Minimizing deadlocks can increase transaction throughput and reduce system overhead because fewer transactions are:

  • Rolled back, undoing all the work performed by the transaction.
  • Resubmitted by applications because they were rolled back when deadlocked.

To help minimize deadlocks:

  • Access objects in the same order.
  • Avoid user interaction in transactions.
  • Keep transactions short and in one batch.
  • Use a lower isolation level.
  • Use a row versioning-based isolation level.
    • Set READ_COMMITTED_SNAPSHOT database option ON to enable read-committed transactions to use row versioning.
    • Use snapshot isolation.
  • Use bound connections.

The "row versioning-based isolation level" may answer your question Or is there a way to ask SQL Server to lock a Row instead of a Table?. There are some notes mentioned in the original source regarding this option.

Here are some other references that came up during my search:

Avoiding deadlock by using NOLOCK hint

How to avoid sql deadlock?

Tips to avoid deadlocks? - This one mentions being careful when using the NOLOCK hint.

The Difficulty with Deadlocks

Using Row Versioning-based Isolation Levels

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top