HTTP is stateless. Your unit of work exists on the server-side only. As for clicking 'Load' then your UOW is simply retrieve the record and map to your view model. 'Save' and unit of work starts when you hit the server - rather than being over the course of the load, edit in browser, and then back to server.
Implementation wise you shouldnt keep the ISession in memory (in your case ASP.Net session object), it a sure fast way to exhausting memory and unmanaged ado.net resources. There are various UOW examples some people choose to associate a ISession with the HTTP Context at begin_request and dispose on end_request, you can of course be more granular, but in all cases it never exists further than that.
In a simplictic system, on hitting the 'Save' you will need to pull the Product out of the database using an ID (hidden field or what not), set the properties from the Request.Form, and then update in the database.
As for concurrency. If you record the timestamp or an increment version in a hidden field
<input type="hidden" name="version" value="12"/>
Then when you hit Save, you pull the Product out of the database, check that the version number in the Request.Form matches and then save, if not return to the user that the data has changed since last retrieved, would you like to proceed? NHibernate has timestamp/version fields so the comparison is done when you actually hit the DB basically a where clause on the Update, so in this instance it even accounts for changes to very moment you commit.
There are more elaborate and sophisticated ways but generally you can't/shouldn't be sticking ISession in your asp.net Session object.