-
Notifications
You must be signed in to change notification settings - Fork 934
NH-3606 - open a stateless session from a session #1520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NH-3606 - open a stateless session from a session #1520
Conversation
fredericDelaporte
commented
Jan 10, 2018
- Fixes NH-3606 - Open a stateless session from a session #910
- Replaces NH-3606 - A method to create a child stateless session #314
@@ -173,6 +173,35 @@ public void FlushFromTransactionAppliesToSharingSession() | |||
} | |||
} | |||
|
|||
[Test] | |||
public void FlushFromTransactionAppliesToSharingStatelessSession() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not added the equivalent test in system transaction, because the "flush from transaction completion" feature is basically broken with stateless sessions. A stateless session accumulates changes as a pending batched command, bound to the current connection. When flushing from a system transaction, this means the command has to execute from the NHibernate enlisted resource prepare phase, potentially after (or concurrently to) its connection own prepare phase.
Maybe it's better to move duplicated code into AbstractSessionImpl? |
I have to check how impactful it would be. Especially if this results in moving |
d94b00b
to
3f765c4
Compare
Done. This causes less changes than what I was expecting. I have still done it in multiple commits in order to allow dropping the last ones if preferring less changes. |
/// A session is considered connected if there is a <see cref="DbConnection"/> (regardless | ||
/// of its state) or if the field <c>connect</c> is true. Meaning that it will connect | ||
/// at the next operation that requires a connection. | ||
/// </remarks> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property concrete implementation being put in common, I have taken the more complete xml documentation.
public ITransactionContext TransactionContext | ||
{ | ||
get; set; | ||
} | ||
|
||
private bool isAlreadyDisposed; | ||
|
||
private static readonly INHibernateLogger logger = NHibernateLogger.For(typeof(AbstractSessionImpl)); | ||
private static readonly INHibernateLogger Log = NHibernateLogger.For(typeof(AbstractSessionImpl)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was unused. With the code moves, it is now used, and renamed by the way.
this, | ||
options.UserSuppliedConnection, | ||
options.SessionConnectionReleaseMode, | ||
Interceptor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overridden in stateless for always returning EmptyInterceptor
, so equivalent to previous code in stateless, which was creating the connection manager with EmptyInterceptor
.
ConnectionManager = new ConnectionManager( | ||
this, | ||
options.UserSuppliedConnection, | ||
options.SessionConnectionReleaseMode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In stateless option, always return AfterTransaction
, so equivalent to previous code in stateless.
public abstract IBatcher Batcher { get; } | ||
// 6.0 TODO: remove virtual. | ||
/// <inheritdoc /> | ||
public virtual IBatcher Batcher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it was abstract, and since AbstractSessionImpl
was public, it would be a breaking change to not allow it to be overridden. But there are nor reason to keep it virtual
, thus the TODO for 6.0. The same applies to a bunch of other properties later in this file.
public abstract bool TransactionInProgress { get; } | ||
// 6.0 TODO: remove virtual. | ||
/// <inheritdoc /> | ||
public virtual bool TransactionInProgress => ConnectionManager.IsInActiveTransaction; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In stateless, this was Transaction.IsActive
instead. It looks to me as an undue discrepancy. I have removed this discrepancy. But it was not having much impact, since this is an unused ISessionImplementor
property. Its documentation backs my change further:
/// <summary>
/// Does this <c>ISession</c> have an active NHibernate transaction
/// or is there a system transaction in progress in which the session is enlisted?
/// </summary>
@@ -218,19 +256,24 @@ public virtual IQuery GetNamedSQLQuery(string name) | |||
} | |||
} | |||
|
|||
// 6.0 TODO: remove virtual from below properties. | |||
/// <inheritdoc /> | |||
public virtual ConnectionManager ConnectionManager { get; protected set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serialization of SessionImpl
constrains to have the setter. Otherwise we should explicitly implement serialization in this base class too. (Which theoretically would imply explicitly implementing it in stateless too, but stateless serialization seems to me already broken.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing this to an automatic property makes it serializable while it was marked as [NonSerialized] before (in StatelessSession).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we were willing to fix serialization for stateless, we would need to serialize it. Not having it serializable is a bug. Since we need to serialize it for SessionImpl
, better reflect that fact. This anyway changes nothing for stateless, since it cannot be deserialized to an usable object currently.
@@ -28,9 +25,6 @@ public partial class StatelessSessionImpl : AbstractSessionImpl, IStatelessSessi | |||
{ | |||
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(StatelessSessionImpl)); | |||
|
|||
[NonSerialized] | |||
private readonly ConnectionManager connectionManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A deserialized session without a connection manager is quite useless. I guess no-one serializes stateless sessions, or maybe we have a bug logged somewhere about it. Anyway, it does not even have a default constructor or a deserialization constructor, so it can only fail deserializing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we have a bug.
I was thinking about this myself, and made a conclusion that StatelessSession is (was always) not serializable. Eg, the connectionManager property would always be null after deserialization. |
@@ -218,19 +256,24 @@ public virtual IQuery GetNamedSQLQuery(string name) | |||
} | |||
} | |||
|
|||
// 6.0 TODO: remove virtual from below properties. | |||
/// <inheritdoc /> | |||
public virtual ConnectionManager ConnectionManager { get; protected set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing this to an automatic property makes it serializable while it was marked as [NonSerialized] before (in StatelessSession).
/// <summary>Get the current NHibernate transaction.</summary> | ||
public ITransaction Transaction => ConnectionManager.Transaction; | ||
|
||
protected bool TransactionCoordinatorShared { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other places it's called "IsTransactionCoordinatorShared". Changing it to an automatic property makes the field serializable, while it was marked as [NonSerialized] before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but no, and without any importance currently, that is why I have not really bothered.
For SessionImpl
, serialization is explicitly done, causing fields from the base class to be serialized only if handled explicitly. It is not in SessionImpl
. Anyway, if it was serialized, it would not change anything, because GetObjectData
throws if it is not false
, so a value other than the default one for its type would not be serialized.
For stateless, well, it could be now serialized, if the stateless was actually serializable, which is still not I believe. Stateless should implement serialization the same way than SessionImpl
, meaning choosing itself what it serialize and if it can be serialized.
Update: I do not think that we should switch away from an automatic property just for being able to signal it is not serialized, while its serialization or non-serialization cannot have any impact currently.
@@ -28,9 +25,6 @@ public partial class StatelessSessionImpl : AbstractSessionImpl, IStatelessSessi | |||
{ | |||
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(StatelessSessionImpl)); | |||
|
|||
[NonSerialized] | |||
private readonly ConnectionManager connectionManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we have a bug.
bf00ee8
to
6315627
Compare
This is not fixing internal troubles since this property has no usages.
Just to get rid of the warning sign (at least with my current settings...).
6315627
to
30d8fe2
Compare
Rebased. |