In a sense BeginRequest()/EndRequest() isn't really your UI code, but more of an "application-framework-kind-of-thing" that follows from how "requests" are handled in that particular style of application. If you want to reuse the same business tier in e.g. a native windows application you might want to handle your sessions differently, so it would not necessarily be a good idea to hide this completely in some sort of data layer.
You should likely use NHibernate's support for contextual sessions to track the active session per request. In your case, the WebSessionContext. http://nhibernate.info/doc/nh/en/index.html#architecture-current-session (Forget about ManagedWebSessionContext, it is deprecated.) Following this, you business/data layer will get the session from sessionFactory.GetCurrentSession(), and not depend on UI code.
Your UI should probably mostly be unaware of NH, except for application setup code in Global.asax. You can also move it to its own IHttpModule. You can of course hide it behind MyDataLayer.StartSession() if you really want to.
You should always use a transaction. What would you gain by not defining one? The database will still use (multiple) implicit transactions.
NHibernate transactions and System.Transaction are different. You can use TransactionScope, but you must in that case also use NH's transaction to avoid some problems.