-
Notifications
You must be signed in to change notification settings - Fork 25
Session
From v10.0 WriteSession and ReadSession has been merged to Session. The concept, as long as the underlying provider supports it, is to represent a minor unit of work accomplished by using transactions and thereby ACID-operations.
The Session
is designed to be short-lived and it is created via the factory method Database.BeginSession()
. You should keep the scope small. Create it and when finished with it, dispose it. The SisoDatabase on the other hand, should be kept alive longer, since it holds cahced schemas, data etc.
The Session
implementation does implement the IDisposable
interface, and as long as the underlying provder supports it, a transaction will be used underneath. From v9.0 auto-commit is used. Hence if there is a transaction and no exception has been thrown, a call to Dispose
will commit the work. The recommended way to use it is in conjunction with an using-block:
using(var session = db.BeginSession())
{
session.Insert(customer);
session.Insert(order);
}
or
db.WithSession(s =>
{
session.Insert(customer);
session.Insert(order);
});
or if you only want to perform a single operation against the session:
db.UseOnceTo().Insert(customer);
The session is used for querying as well:
using(var session = database.BeginSession())
{
customers = qe.Query<Customer>().Where(c => c.Lastname == "Andersson").ToList();
}
simplified for single read operations:
var customers = db.UseOnceTo().Query<Customer>().Where(c => c.Lastname == "Andersson");
As the name implies. The use-case is when you know you are doing one call within the same session. If you are doing two operations after eachother, use a session instead.
The Session has from v14.0.0, gained a simple GUID, Id-property
which can be used to identify sessions. It is useful if you e.g. implement a hook on session.Events.OnCommited
, where you can make use of it to take actions on buffered data.
The Status
member of ISession
can be used to investigate the state of the session. The state can be:
[Serializable]
public enum SessionStatus
{
/// <summary>
/// Session is active and healthy.
/// </summary>
Active,
/// <summary>
/// Session has been aborted but has not yet been disposed.
/// </summary>
Aborted,
/// <summary>
/// Session has failed but has not yet been disposed.
/// </summary>
Failed,
/// <summary>
/// Session without failures has been disposed.
/// </summary>
Disposed,
/// <summary>
/// Aborted session has been disposed.
/// </summary>
DisposedAfterAbort,
/// <summary>
/// Failed session has been disposed.
/// </summary>
DisposedWithFailure
}
Some helpers exists:
session.Status.IsAborted();
session.Status.IsFailed();
session.Status.IsDisposed();
From v16.0.0, the session exposes Abort()
and MarkAsFailed()
. You could make use of this in a custom HttpModule
where you setup a "one SisoDb-session per-request" behavior, and want to react on some exception and then force a rollback, but only if Session.Status.IsDisposed() == false
, otherwise it's already to late.
As of v16.0.0 and v16.1.0 there are a couple of hooks that you can use on the session. These can be used to e.g. build up a buffer of db-changes, like inserts, which OnCommitted
could be persisted to e.g Lucene or published on a service-bus or whatever.
public interface ISessionEvents
{
/// <summary>
/// Called when a session is disposed and committed.
/// </summary>
Action<ISisoDatabase, Guid> OnCommitted { set; }
/// <summary>
/// Called when a session is rolled back and disposed due to an failure.
/// </summary>
Action<ISisoDatabase, Guid> OnRolledback { set; }
/// <summary>
/// Called when an item has been inserted.
/// </summary>
Action<ISession, IStructureSchema, IStructure, object> OnInserted { set; }
/// <summary>
/// Called when an item has been updated.
/// </summary>
Action<ISession, IStructureSchema, IStructure, object> OnUpdated { set; }
/// <summary>
/// Called when delete has been performed on an id.
/// </summary>
Action<ISession, IStructureSchema, IStructureId> OnDeleted { set; }
/// <summary>
/// Called when delete has been performed by a query.
/// </summary>
Action<ISession, IStructureSchema, IQuery> OnDeletedByQuery { set; }
}