JimFoye wrote:
Frans,
I'm liking this UnitOfWork2 class. I noticed when I add an entity for save, I can also add a predicate expression to handle concurrency.
1) I'm filling the UnitOfWork2 with changed entities in my GUI and then calling my manager class to save the work.
public void Save(UnitOfWork2 uow)
{
uow.Commit(adapter, true);
}
I like managing the uow object from the GUI, and this seems to me how other folks are doing it, too. But, shouldn't the concurrency be the domain of the BLL? Shouldn't the GUI say, "here, save this for me", and the BLL say, "sure, let me just make sure when I do I don't overwrite someone else's changes"? But to do this it would have to have some way of inspecting the UOW's collection of objects to be saved. Would not be very pretty.
true, however how I see it is that the GUI in that scenario gets objects from the BL and the BL already sets the concurrency predicate factory of the entity, which makes sure the concurrency is preserved.
2) As expected, if I modifed the record outside of my app, the update failed. But...how do I trap for this so I can tell user his update failed because someone else changed the record?? I think in self-servicing I checked the return value of Save(). Commit() returns void.
You can't, and that's a problem of the way things are reported back: the number of rows affected. Say you update a row: this can fail because the concurrency filter fails, but it can also fail because the row is deleted. Either way, 0 rows affected is reported by the DB.
Simply put: if a user sends away a set of actions to get preserved into the db, that's an atomic action, and it either fails or succeeds as a whole. If somewhere a row failed and caused the whole action to terminate because the concurrency predicate made the update to fail, the whole commit has to fail, as it is an atomic action.
it is also too late, the user who has made changes which are not allowed to overwrite other people's changes WILL be lost, otherwise these other people's changes should be overwritten. So the person who runs into this, will have his work being dropped, as it can't be saved. It's then better to preserve this in the first place, by disallowing people to alter an object if another person is already editing it, for example by locking out functionality to edit these objects.
Plus, now with this UnitOfWork2 class I may be letting the user cache several related detail records before he clicks a button to save. Wow! What if there is some concurrency conflict with the PO header and the user has typed in 10 detail records? Perhaps this is not strictly a LLBLGen question, maybe more a general philosophical one.
I think it's the common what to do with 2 people changing teh same data problem:
http://weblogs.asp.net/fbouma/archive/2003/05/24/7499.aspx