[SPRNET-1160] Synchronizations with the same (or no) Order are NOT applied in registration order Created: 08/Feb/09  Updated: 04/Mar/09  Resolved: 04/Mar/09

Status: Resolved
Project: Spring.NET
Component/s: Spring-NET-TX
Affects Version/s: 1.2.0
Fix Version/s: 1.3.0 RC1

Type: Bug Priority: Major
Reporter: Ben Rowlands Assignee: Erich Eichinger
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on SPRNET-1178 add utility methods for stable sortin... Resolved

 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.



 Comments   
Comment by Erich Eichinger [ 04/Mar/09 ]

syncs are sorted stable now - Ben, tx a lot for investigating and reporting!

Generated at Sat Jan 25 16:57:29 UTC 2020 using Jira 7.13.8#713008-sha1:1606a5c1e7006e1ab135aac81f7a9566b2dbc3a6.