How to reproduce DeadLock issue in AX 2009.

Hi All,

I have a deadlock issue, I do not know how to reproduce the issue.

Can anyone let me know how we can re produce the dealock issue in AX 2009…?

Thanks In Advance…!

I don’t know what issue you have, but I do know how to create a deadlock. The easiest way I’m aware of:

  1. Find/create a table using pessimistic locking (OccEnabled=No), e.g. InventSum.
  2. Let two AX instances to lock two records, but in opposite order.

The real issue here is timing - fortunately you can use pause statement or Box class to stop the transaction unless you confirm the dialog.

A concrete example:

Create two batches locking InventSum table (use your own item IDs).

static void deadlock_A(Args _args)
{
    InventSum inventSum;

    ttsBegin;

    select firstOnly forUpdate inventSum
        where inventSum.ItemId == "ItemA";

    pause;

    select firstOnly forUpdate inventSum
        where inventSum.ItemId == "ItemB";

    ttsCommit;
}

static void deadlock_B(Args _args)
{
    InventSum inventSum;

    ttsBegin;

    select firstOnly forUpdate inventSum
        where inventSum.ItemId == "ItemB";

    select firstOnly forUpdate inventSum
        where inventSum.ItemId == "ItemA";

    ttsCommit;
}

Start two AX clients and run deadlock_A in the first one - don’t confirm the Pause dialog yet. Run deadlock_B in the other client - it will lock ItemB and try to lock ItemA, but that’s already locked, so the job waits for the lock to be released. Then go back to deadlock_A and let the code continue. It will try to lock ItemB, but that’s locked, so it have to wait. Now the transactions are waiting for each other, unable to go forward. SQL server will detect the problem, rollback one of the transactions and throw the exception you can see in AX infolog.

Hi Martin,

Thanks for you quick response and very helpful explantion which gives me confidence to push my fix to Testing by able to reproducing the Deadlock issue.

After a user test of my code, there is a bit improment but still the issue was there (i.e No.of Deadlocks are decreased but still there are some of them.)

Actual Issue :

We have a AIF service class to create web orders from website. That class is calling Update( ) of CustTable and Address Table. when we look into the code of both update methods there is a call to DirParty class where a pessimistic lock is applied to read a record on DirPartyTable.

So I have changed the update calls to both CustTable and Address table as from Update( ) to doUpdate.

AIF Exception :

Deadlock - AIF AifRequestProcessor-executeServiceOperation Cannot execute the required database operation.

Deadlock, where one or more users have simultaneously locked the whole table or part of it.

Please let me know your Ideas to fix this issue.

Thanks In Advance…

It’s not clear from your post what and why was deadlocked. If you’re not sure, first collect deadlock tracing in SQL server - you will get information about what resource was deadlocked and the queries involved. Then identify the queries in X++ and how the code is called. Sometimes you can change order of operations so the second operation waits for the first one, or you may be even forced to introduce a special lock preventing other threads from accessing some logic in the same time (be sure that this is held is as shortly as possible). Sometimes you find that the lock is applied to more resources than needed and you can influence that by restructuring queries, indexes and so on. Sometimes you can split things to more transactions. And so on. There is not just a single cause and just a single solution.

If you’re replacing update() with doUpdate(), be very sure that you don’t need any logic implemented in update(). Update() methods often contain code important for maintaining database integrity.