views:

89

answers:

4

In essence this is a followup of this question. I'm beginning to feel that I should give up the whole idea, but I'll give it one more shot.

What I want is pretty much like a DB transaction. It should track my changes to the DB and then in the end allow me to either commit or rollback them. If I insert an object, I should get it back in my next (appropriate) SELECT query. If I delete it, future SELECT queries should not return it. Etc.

But there is one catch - this transaction would be very long running. It would start when the user opened a form (I'm talking about Windows Forms here), and the commit/rollback would be when the user closed it(with OK/Cancel). So it could take anywhere between seconds and days. This requirement rules out a standard DB transaction because that would lock the tables/rows it touched, and other users wouldn't be able to use the system. Also the transaction should not commit ANY changes to the DB until it was really committed. So if one user makes some changes, others don't see them until OK button is hit. This prevents errors in case the computer crashes or is disconnected from the network.

I'm quite OK if the solution puts constraints on my model (I'm using MSSQL 2008, btw). I can design the DB/code any way I like. I'm also fine with the idea that a commit could fail because someone already modified one of the objects my transaction touched.

Is there anything like this? I looked at NHibernate.Burrow, but I'm not sure that that's the thing I want.

Added: It's the very beginning of the project so I'm not tied to NHibernate. I started out with it but I can still change easily.

A: 

This is not a direct answer to your question, but this is the sort of thing that WWF (gotta love the name) was set out to solve (not that it did so at least by v 3.5).

Kevin Won
+1  A: 

I don't think anyone will implement this in the NHibernate core, because nobody will use it. Viewmodel is not the same model as domain model.

Paco
Doesn't matter if it's in NHibernate, on top of it, or completely unrelated to it. It's just that right now I'm using NHibernate, but it's the very start of the project, so I can still change if I want to.
Vilx-
+3  A: 

As far as I can judge, DataObjects.Net supports exactly this concept via DisconnectedState. The feature is very new (released just few weeks ago), its preliminary documentation is here. WPF sample for DataObjects.Net uses it for UI transactions.

I'm not sure if it is mentioned there, but DisconnectedState, as well as its OperationLog can be serialized. So its cached state can survive even application restarts.

Alex Yakunin
Not bad. I'd use it, except this is a small commercial program I'm doing in my spare time, so I'm both unwilling to go GPL with it, and I don't have enough money to buy it. :( But great find! I'll definately keep this in mind for the future!
Vilx-
Another limitation is that Entity, inserted into DisconnectedState and not saved to database can be selected by query to database, except fetch-by-key query. But I can say that it's essential limitation, it's hard to figure out how such queries should work.
Alex Kofman
Err... You mean "can not be selected"?
Alex Yakunin
Yes, "can NOT be selected"
Alex Kofman
A: 

If you're still following this, Ayende Rahien has an article in MSDN magazine http://msdn.microsoft.com/en-us/magazine/ee819139.aspx about the session per form/presenter approach. Also take a look at chapter 5 of the NHibernate book http://manning.com/kuate/ (sample chapter available), the one on transactions and conversations.

As long as you delay the flush/transaction till the ok button is pressed, it should work (depending on the flush mode). But complete isolation is a difficult ask because your session will be able to access data that has been committed by other sessions when dealing with multiple entities. You will have to think about handling such issues.

As an aside, how would you deal with this situation if you don't use NHibernate?

Interesting article, I'll read it later. If I didn't use NHibernate I'd probably do change tracking myself and then write all changes at once in a transaction at the press of the "OK" button. I don't know how I'd handle the SELECT problem though.
Vilx-