views:

37

answers:

1

I have the need to persist a calculated property with an aggregate root. The calculation is based on child entities. I am using the root to add/remove the children via domain methods, and these methods update the calculate property.

A child entity can be added to a particular root by multiple users of the system. For example, UserA can add a child to Root123, and UserB can also add a child to Root123.

How can I ensure that this calculated property is persisted accurately when more than one user may be adding child entities to the same root in different transactions? In my particular case, the calculated property is used to ensure that some limit is not exceeded, as set by another property on the root.


Here is a more concrete example of the problem:

public class RequestForProposal : AggregateRoot {
    ...
    private ISet<Proposal> _proposals = new HashedSet<Proposal>();

    public virtual int ProposalLimit { get; set; }
    public virtual int ProposalCount { get; protected set; }

    public virtual IEnumerable<Proposal> Proposals {
        get { return _proposals; }
    }
    ...

    public virtual void AddProposal(User user, Content proposalContent) {
        if (ProposalCount >= ProposalLimit) {
            throw new ProposalLimitException("No more proposals are being accepted.");
        }

        var proposal = new Proposal(user, proposalContent);
        _proposals.Add(proposal);
        ProposalCount++;
    }

    public virtual void RemoveProposal(Proposal proposalToRemove) {
        _proposals.Remove(proposalToRemove);
        ProposalCount--;
    }
}

What if 2 users are submitting their proposals at roughly the same time? The UI sees that the limit has not yet been reached and shows the Web page to submit a proposal for both users. When the first user submits, all is well. Now, the second user will be okay as long as the first user submits before the second one, so that when the second user submits, the data is retrieved from the DB and the limit will be accurate.

Is this a moot point? Should I rely on constraints in the DB (ProposalLimit >= ProposalCount) for those rare cases where 2 users submit nearly simultaneously?