View Full Version : AfterCommit in SpringSessionSynchronization
pathakn
01-05-2007, 05:31 PM
Hi
In the latest nightly build the code for AfterCommit is not implemented. Is this an oversight or am I missing something?
Thanks,
-Nilesh
pathakn
01-05-2007, 05:33 PM
Same is the case with AfterCompletion....
pathakn
01-05-2007, 06:04 PM
Further to this in HibernateTransactionManager's DoResume method...
I am seeing strange behaviour...
protected override void DoResume(object transaction, object suspendedResources)
{
SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources;
if (TransactionSynchronizationManager.HasResource(Ses sionFactory))
{
// From non-transactional code running in active transaction synchronization
// -> can be safely removed, will be closed on transaction completion.
TransactionSynchronizationManager.UnbindResource(S essionFactory);
}
TransactionSynchronizationManager.BindResource(Ses sionFactory, resourcesHolder.SessionHolder);
if (DbProvider != null)
{
TransactionSynchronizationManager.BindResource(DbP rovider, resourcesHolder.ConnectionHolder);
}
}
I have an Insert and an Update back to back and what I am seeing is that both statements are executed fine but in the above method it breaks trying to look for suspendedResources...which is null. When TransactionSynchronizationManager.BindResource(Ses sionFactory, resourcesHolder.SessionHolder) is invoked the resourceHolder is null and that causes the whole thing to break...
Any help? Also what's the last stable version of Spring.Data.NHibernate I can use?
Mark Pollack
01-05-2007, 09:26 PM
Hi Nilesh,
I'll look into it and get back to you shortly. The latest build from the download page is what you should be using. Follow the links on the modules (http://www.springframework.net/modules.html)page. Thanks for reporting these issues.
Mark
pathakn
01-06-2007, 04:05 AM
Well..that's where I got it from...
Followoing is how I have set up my declarative transactions...do you see any problem with below? <d:dbProvider id="DbProvider"
provider="System.Data.OleDb"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\Temp\class.ttb;User Id=;Password="/>
<object id="SessionFactory" type="AbleSoft.TTBox.Service.NHibernateService, TestHibernateTemplates" singleton="true" init-method="Start" >
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingResources">
<list>
<value>TestHibernateTemplates.AbleSoft.TTB.Domain.Class.h bm.xml, TestHibernateTemplates</value>
<value>TestHibernateTemplates.AbleSoft.TTB.Domain.Student Class.hbm.xml, TestHibernateTemplates</value>
<value>TestHibernateTemplates.AbleSoft.TTB.Domain.Student .hbm.xml, TestHibernateTemplates</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="hibernate.dialect"
value="NHibernate.JetDriver.JetDialect, NHibernate.JetDriver"/>
<entry key="hibernate.connection.driver_class"
value="NHibernate.Driver.OleDbDriver, NHibernate"/>
<entry key="hibernate.show_sql"
value="true"/>
</dictionary>
</property>
</object>
<!-- Declarative Transaction based on AOP -->
<object id="TransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate">
<property name="SessionFactory" ref="SessionFactory"/>
<property name="AutodetectDataSource" value="false"/>
<property name="DbProvider" ref="DbProvider"/>
</object>
<object id="ServiceAutoProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxy Creator, Spring.Aop">
<property name="InterceptorNames">
<list>
<idref local="TxInterceptor"/>
</list>
</property>
<property name="ObjectNames">
<list>
<value>*DAO</value>
</list>
</property>
</object>
<object id="TxInterceptor" type="Spring.Transaction.Interceptor.TransactionIntercep tor, Spring.Data">
<property name="TransactionManager" ref="TransactionManager"/>
<property name="TransactionAttributes">
<name-values>
<add key="Add*" value="PROPAGATION_REQUIRES_NEW"/>
<add key="Save*" value="PROPAGATION_REQUIRES_NEW"/>
<add key="Update*" value="PROPAGATION_REQUIRES_NEW"/>
<add key="Delete*" value="PROPAGATION_REQUIRED"/>
</name-values>
</property>
</object>
Mark Pollack
01-06-2007, 06:27 PM
Hi Nilesh,
I downloaded the 1.0.2 NH module Spring.Data.NHibernate-20070106-0103 and the method AfterCompletion is implemented, which version are you using exactly? It is ok for AfterComplete to be a no-op. I will introduce a class "TransactionSynchronizationAdapter" which will contain no-ops for all the methods on ITransactionSynchronization (as in the Java version) so this doesn't raise any eyebrows.
I do see your point with the null value. I will look into it further. In the meantime, the reason you are going down that pathway is because you have used PROPAGATION_REQUIRES_NEW as the propagation behavoir. This will create a new tx and suspend the current tx if it exists. I don't see the need for that in this case. You should use PROPAGATION_REQUIRES instead. Then your Add and Update will be in the same transaction. The sequence of events will be to create the transaction before "Add" and then "Update" will participate in that transaction.
Hope this helps, let me know.
Cheers,
Mark
pathakn
01-06-2007, 07:09 PM
Makes sense. Let me give it a shot.
javajunky
05-30-2007, 01:08 PM
Hi Guys,
I'm not certain this is related, but I've just created my first transaction that has a propagation setting of PROPAGATION_REQUIRES_NEW (propagation requires new for forum search ;) ). To date, all of my transactions have performed beautifully, but now all of a sudden things are falling over :(
(I see various errors about 'Unable to find SessionFactoryImpl for key in thread or something to those words)
I believe the underlying issue is this occurs:
2007-05-30 12:33:26,240 [9] ERROR Spring.Transaction.Support.AbstractPlatformTransac tionManager [(null)] <(null)> - TransactionSynchronization.AfterCompletion threw exception
System.NullReferenceException: Object reference not set to an instance of an object.
at Spring.Data.NHibernate.SpringSessionSynchronizatio n.AfterCompletion(TransactionSynchronizationStatus status)
at Spring.Transaction.Support.AbstractPlatformTransac tionManager.InvokeAfterCompletion(IList synchronizations, TransactionSynchronizationStatus status)
Is there anything special I should be doing, I *thought* that just marking that method as 'requires-new' would mean that a new transaction would be started and commited (or roll-backed) for that method, regardless of whether it was called from another method that was in a transaction or not!...
Is this the same issue ?
javajunky
05-30-2007, 04:07 PM
Hmm, 3 hours later and I've got a debug build, built, I've got some questions about this code:
public override void AfterCompletion(TransactionSynchronizationStatus status)
{
if (!newSession)
{
ISession session = sessionHolder.Session;
// Provide correct transaction status for releasing the Session's cache locks,
// if possible. Else, closing will release all cache locks assuming a rollback.
ISessionImplementor sessionImplementor = session as ISessionImplementor;
if (sessionImplementor != null)
{
sessionImplementor.AfterTransactionCompletion(stat us == TransactionSynchronizationStatus.Committed);
}
if (newSession)
{
SessionFactoryUtils.CloseSessionOrRegisterDeferred Close(session, sessionFactory);
}
}
if (!newSession && status != TransactionSynchronizationStatus.Committed)
{
// Clear all pending inserts/updates/deletes in the Session.
// Necessary for pre-bound Sessions, to avoid inconsistent state.
sessionHolder.Session.Clear();
}
if (this.sessionHolder.DoesNotHoldNonDefaultSession) {
sessionHolder.SynchronizedWithTransaction = false;
}
}
My Code is falling over at the sessionHolder.Session.Clear() line, which I assume means that the sessionHolder, doesn't hold one??
Whilst I'm looking at this code, I have to admit my C# isn't all that strong, but it seems to me that the section:
if (newSession)
{
SessionFactoryUtils.CloseSessionOrRegisterDeferred Close(session, sessionFactory);
}
Will never ever get called, as it is nested within a test for !newSession (which is declared as readonly and only set once in the constructor)
What is meant to be happening here ?
many thanks guys :)
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.