Is there something like a "long running offline transaction" for NHibernate or any other ORM? - nhibernate

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.

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.

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.

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).

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?

EclipseLink has limited supported for such a beast. They call it "Conforming" and they implemented it in the "unit of work" context.

Related

TransactionLog as EventsStore

I've heard many times that relational databases' Transaction Log is one of original implementations of EventStore. In theory using TransactionLog as an EventStore sounds like a nice idea as we can get snapshots for free (tables data represent snapshot).
But I've never seen any attempts to use TransactionLog as an EventStore for CQRS. May be I just missed it. If not, what other potential reasons for that? Is TransactionLog a low level thing that could not be exposed for manual manipulation? Is it synchronous and tables values (snapshot) can not be delayed? Or is it just a bad idea for any other reason?
IMHO an eventstore is more than a list of transactions. The key idea is that it describes why changes were made, not just what changes were made. For example, you may see that the address was updated in a transaction log. But in an eventstore, you would see that the customer moved house.
A well crafted events are human readable. A domain expert would be able to give you a clear understanding of what was happening in a system by reading the event names in the eventstore. I've written more about this in my post 6 Code Smell with Your CQRS Events (And How to Avoid Them)
However, from a purely technical perspective, maybe it could be done. I'm just not sure why you would want to.
I hope that makes sense.

Keeping History in Entity Framework/ Sql Server

I need to be able to save all the data that gets updated like so.
User inserts a car Model (Make, Type, Year). Comes back and Updates the Year. I need to be able to save both so they have a history of all the work that they did. What is the best way to do that?
There are a number of ways to do this. One way is to write some SQL triggers and do it entirely in the database. Have a look here for some clues:
Another way is to do the auditing within the Entity Framework code. There is a nuget package called AuditDbContext with the source on Codeplex.
You need to decide if you want to do the auditing in EF or in SQL. Obviously if you need to audit everything and you might sometimes access the database from different applications which don't use the same EF datalayer (e.g. different technologies, etc), then SQL triggers might well be the way to go.
Maybe (if you are facing the "history" issue more often) the CQRS pattern is of interest for you; a good primer, Microsoft on CQRS. There is a framework build on .NET for this pattern (I have not tried it yet): NCQRS.
If you really just want the requirement in your question fulfilled now and you are using SQL Server 2010 or later, then Change Tracking may be another option. I would prefer that to triggers (but in the end all such dark processing logging solutions introduce additional risk).

nhibernate lazy loading uses implicit transaction

This seems to be a pretty common problem: I load an NHibernate object that has a lazily loaded collection.
At some later point, I access the collection to do something.
I still have the nhibernate session open (as it's managed per view or whatever) so it does actually work but the transaction is closed so in NHprof I get 'use of implicit transactions is discouraged'.
I understand this message and since I'm using a unit of work implementation, I can fix it simply by creating a new transaction and wrapping the call to the lazy loaded collection within it.
My problem is that this doesn't feel right...
I have this great NHibernate framework that gives me nice lazy loading but I can't use it without wrapping every property access in a transaction.
I've googled this a lot, read plenty of blog posts, questions on SO, etc, but can't seem to find a complete solution.
This is what I've considered:
Turn off lazy loading. I think this is silly, it's like getting a full on sports car and then only ever driving it in eco mode. Eager loading everything would hurt performance and if I just had ids instead of references then why bother with Nhibernate at all?
Keep the transaction open longer. Transactions should not be long lived and keeping one open as long as a view is open would just be asking for trouble.
Wrap every lazy load property access in a transaction. Works but is bloaty and error prone. (i.e. if I forget to wrap an accessor then it will still work fine. Only using NHProf will tell me the problem)
Always load all the data for the properties I might need when I load the initial object. Again, this is error prone, both with loading data that you don't need (because the later call to access it has been removed at some point) or with not loading data that you do
So is there a better way?
Any help/thoughts appreciated.
I has had the same feelings when I first encountered this warning in NHProf. In web applications I think the most popular way is to have opened transaction (and unit of work) for the whole duration of request. For desktop applications managing transactions (as well as sessions) may be painful. You can use automatic transaction management frameworks (e.g. Castle) and declare with attributes service methods that should be run within transaction. With this approach you can wrap multiple operations into single transaction denending on your requirements. Also, I was using session-per-view approach with one opened session per view and manual transaction management (in this case I just ignored profiler warnings about implicit transactions).
As for your considerations: I strongly don't recommend 2) and 3). 1) and 4) are points to consider. But the general advice is: think, then try different approaches and find a solution that suits better for your particular situation.

NHibernate - flush before/after select?

Currently I am working on a project, that was programmed by someone else and it is known that the NHibernate part might not be well implemented. I was asked to improve that during my internship, but I am also very new to NHibernate.
I came across some code parts where there was a Flush after a select, in my opinion that is completely useless, am I right (question 1)?
I read almost the complete NHibernate Documentation but I am not sure I understand everything.
Should I flush before a select (question 2)? My thoughts are that the data would be up to date when I select after a flush.
(Currently the program doesn't use any transactions at all - I see a lot of room for improvement there)
NH Official documents say:
9.7.1. Flushing the Session
If you happen to be using the ITransaction API, you don't need to
worry about this step. It will be performed implicitly when the
transaction is committed. Otherwise you should call ISession.Flush()
to ensure that all changes are synchronized with the database.
You should always use transactions, even for a read.
If you're not using transaction you should use Flush after a write.
It doesn't really make sens to Flush after a read.
Have a look a these two answers where everything is explained very well.

ORM & Logical Delete

Do any of the available ORMs support using a bit field to represent row removal?
More information. Working in C#. I need to delete this way to support synchronization of remote database changes to a central database. I'm looking for a possible ORM, but am also interested in approaches to the problem. So if anyone knows any ORM in any language/environment that addresses this problem I would be interested in looking at it. Thanks for the questions feel free to ask more if anything is unclear.
This may not apply if you're not using .NET, but the LightSpeed ORM has a built in feature called "soft delete". Basically, when you have a DeletedOn field on your table LightSpeed will insert the time it was deleted. It automatically handles this on normal selects (e.g. where Deleted == null) so that the deleted items are not seen again. You could then write a sync process that detects the deleted state by checking that field.
You can of course instruct the querying engine to include deleted results.
Mindscape LightSpeed ORM
I am making an assumption also that we're talking about the same thing here :-)
I recommend to implement logical delete externally in your application, cause it's not very complex, but it will be more flexible. See this article for details.