Skip to content

NH-3985 - Bugfix for subsequent child sessions being returned in disposed state #600

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

Merged
merged 1 commit into from
Apr 25, 2017

Conversation

alobakov
Copy link
Contributor

@alobakov alobakov commented Apr 16, 2017

NH-3985 - Test case and fix for subsequent child sessions being returned in disposed state

<generator class="identity" />
</id>
<property name="Name" type="String">
<column name="Name" not-null="true" length="50" sql-type="NVARCHAR(50)" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid specifying db specific types. Better not specify any type at all, NHibernate infers them.


#endregion

public virtual int ProcessID { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle will use decimal instead for identities/sequences, so Oracle build may failed due to this.

<class name="Process" table="Processes">
<id name="ProcessID" type="Int32">
<column name="ProcessID" not-null="true" sql-type="INT" />
<generator class="identity" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identity with Oracle use decimal. Using native as generator would be safer by the way, current NHibernate Oracle dialect does not implement identity though Oracle supports it. I believe it does fallback to sequence nether-less, so will work like native, but at least for native that is its documented behavior.

You may also consider using an app side generator like guid.comb, that helps avoid db specific issues.

@alobakov
Copy link
Contributor Author

Doh... Man, thanks for all the reminders. That was a total brain fart on my part. :))

  • Will fix.

@alobakov alobakov force-pushed the master branch 2 times, most recently from c2b5b0a to 07fedc2 Compare April 16, 2017 17:58
@alobakov
Copy link
Contributor Author

alobakov commented Apr 16, 2017

Ok, fixed that. - Let me know if anything else doesn't look right.
BTW, is there a way to re-run the build and tests on the existing pull request to verify that Oracle-related tests would now succeed? Or should I just close this PR and submit a new one?

var childImpl = _childSession as SessionImpl;

// if child session never existed or has already been disposed, create new
if (childImpl == null || childImpl.IsAlreadyDisposed)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if instead of this check we remove the reference on disposal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I'm doing in the implementation of NH-3986 with a collection of child sessions, but that will come in as a separate pull request. If both end up included in the same release, this becomes moot point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 2 points to implement the correct logic here:

  1. It can be back-ported (why? because this is actually a bug) to previous versions without a lot of work required

  2. I'm not yet sure that the improvement will make it to 5.0

@@ -3248,6 +3250,9 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="NHSpecificTest\NH3985\Mappings.hbm.xml">
<SubType>Designer</SubType>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No designer please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I didn't like that either, but Visual Studio seems to keep adding it. Not sure exactly what it means and why it gets added for some mapping files while not others.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's plenty of other hbm.xml files with this sub-element, but only select items have it. - Very odd.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -3248,6 +3250,9 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="NHSpecificTest\NH3985\Mappings.hbm.xml">
<SubType>Designer</SubType>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's plenty of other hbm.xml files with this sub-element, but only select items have it. - Very odd.

@@ -3248,6 +3244,7 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="NHSpecificTest\NH3985\Mappings.hbm.xml" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this and other SubType elements, however it seems to have been an ongoing issue with Visual Studio since VS2005, so there's no clear way to eradicate them once and for all. They appear to be completely harmless though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

These tags become harmful when you try to merge branches as they provide false anchors for the merge tools.

@hazzik
Copy link
Member

hazzik commented Apr 23, 2017

I modified your PR to remove child session from parent as soon as it gets disposed.

@hazzik hazzik force-pushed the master branch 2 times, most recently from 68e06d4 to b24a75a Compare April 23, 2017 22:38
@hazzik
Copy link
Member

hazzik commented Apr 23, 2017

@alobakov next time please make sure that PR is made from a branch, not from master.

@alobakov
Copy link
Contributor Author

Ok will do.
It did have its own branch in my fork, though there were no specific instructions in CONTRIBUTING.md

@fredericDelaporte
Copy link
Member

The Commit your Test Case section tells it. Maybe a bit late in this guide. Not sure it mandates a change.

@@ -1681,6 +1682,9 @@ private void Dispose(bool isDisposing)
// free unmanaged resources here

IsAlreadyDisposed = true;

rootSession?.RemoveChildSession(this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved to Close method, otherwise a closed child-session may be returned by GetChildSession although they are unusable.


void RemoveChildSession(ISession session)
{
Interlocked.CompareExchange(ref _childSession, null, session);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Session is not thread safe, so we should not care about thread safety here.

I know there is a case where Dispose can be called from another thread: when a transaction in which the session was enlisted ends. But this case is buggy and doomed anyway: the child-session is already awaiting disposal (TransactionContext.ShouldCloseSessionOnDistributedTransactionCompleted being true) and should already be considered unusable for any other purpose than ending that transaction. So having it still returnable by its parent session is a trouble.

Being thread safe here will not help avoid troubles. Either we should ensure the child session is immediately removed from its parent on child dispose/close call, even when its disposal is postponed due to an ongoing transaction (TransactionContext not null), or we should cease postponing disposal when there is an ongoing transaction, as Hibernate do with JdbcContext. In both cases, we would no more be exposed to the transaction completion occurring on a distinct thread trouble.

Copy link
Member

@fredericDelaporte fredericDelaporte Apr 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just seeing now these commit comments on the same subject.

In do not really get how another child-session could be there with current implementation. But well, if it is not about thread-safety but only for not removing another one, I would rather implement it without any threading helper, with a if or iif.

It would be more explicit what is currently done here. Using the threading helper without a comment to tell why will let any later reader to wonder why is it coded that way, are there any need to be thread safe here, ...

@hazzik
Copy link
Member

hazzik commented Apr 25, 2017

Changed as per review comments

@hazzik hazzik merged commit 4558d53 into nhibernate:master Apr 25, 2017
@hazzik
Copy link
Member

hazzik commented Apr 25, 2017

Thanks everyone. Squashed and applied to master now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants