Uploaded image for project: 'Spring.NET'
  1. Spring.NET
  2. SPRNET-1160

Synchronizations with the same (or no) Order are NOT applied in registration order

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.0
    • Fix Version/s: 1.3.0 RC1
    • Component/s: Spring-NET-TX
    • Labels:
      None

      Description

      .NET ArrayList.Sort() does not perform a stable sort. If 2 items are equal, insertion order is not preserved. This is different to Collections.sort() in Java which guarantees a stable sort. The leads to Synchronizations registered with the TSM not been applied in the order in which they are registered (a sort is applied when accessing the syncs).

      In my use-case I am registering synchronizations to flush inserts and updates to a database. It is important that these synchronizations are applied in a stable order. If not an update may run before the insert has created the row. I can work around this by explicitly setting the order on inserts so they are run first but this is error prone. Its more natural to just use the error in which the synchronizations were registered as the programmer only has to express their intent once.

      The code below shows this re-ordering of equal items:

      public static void Main(string[] args)
      {
      TransactionSynchronizationManager.InitSynchronization();

      // expect syncs to be run A, B, C, D, E since all have order '1'
      TransactionSynchronizationManager.RegisterSynchronization(new Sync("A", 1));
      TransactionSynchronizationManager.RegisterSynchronization(new Sync("B", 1));
      TransactionSynchronizationManager.RegisterSynchronization(new Sync("C", 1));
      TransactionSynchronizationManager.RegisterSynchronization(new Sync("D", 1));
      TransactionSynchronizationManager.RegisterSynchronization(new Sync("E", 1));

      // simulate what APTM does
      foreach (Sync s in TransactionSynchronizationManager.Synchronizations)

      { Console.Out.WriteLine(s); }

      }

      private class Sync : TransactionSynchronizationAdapter, IOrdered
      {
      private readonly string name;
      private readonly int order;

      public Sync(string name, int order)

      { this.name = name; this.order = order; }

      public int Order { get

      { return order; }

      }

      public override string ToString()

      { return name; }

      }

      On my machine this prints:

      D
      E
      C
      A
      B

      The only stable sort I have found in .NET is Linqs Enumerable.OrderBy().

      Arguably this is a more general problem with any Spring framework feature that allows the use of the Ordered mixin since it is not deterministic.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                oakinger Erich Eichinger
                Reporter:
                benrowlands Ben Rowlands
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: