Based on the comments of the marked answer the feature is already implemented in HN and the solution is as follows:
var result = await session
.Query<Company>()
.WithOptions(x => x.SetReadOnly(true))
.ToListAsync();
Best approach based on my experience (isolation level ReadCommitted).
The following session does not require database modifications:
// Readonly mode is used for running only READ queries without any changes. Flush mode is not needed.
using (var session = sessionFactory.WithOptions().FlushMode(FlushMode.Never).OpenSession())
{
session.DefaultReadOnly = true;
// Do your read only queries here
}
The following session used when some modifications are required but we do not want to lock tables which are not going to be modified:
// The Flush (send all pending changes to the db) will be executed automatically on Commit.
using (var session = sessionFactory.WithOptions().FlushMode(FlushMode.Commit).OpenSession())
{
// Read committed with snapshot (https://stackoverflow.com/a/1664236/1143349)
using (var tran = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
// We are not modifiing settings so we can get a record in readonly mode
// Because of readonly, we do not lock the [settings] table for the time of that transaction.
// So, other sessions can use that table too at the same time.
var setting = session.Query<Setting>()
.WithOptions(x => x.SetReadOnly(true))
.Where(x => x.Key == "IsTenantRequired")
.SingleOrDefault();
if (setting?.Value == true)
{
var newTenant = new Tenant("My Tenant Name");
session.Save(newTenant);
}
// Do your other transactional changes
// but you promised to not touch the [settings] table (no modifications)
// in the current transaction.
tran.Commit();
} // Rollback happens here in case of errors
} // Session is closed here