I am using Spring .NEt and NHibernate along with ASP .NET MVC.
Recently I decided to integrate transaction management with Spring. I understand spring give a way to easily integrate transation using the [Transaction()] attribute on your service. I got this to work.
My old architecture was to intercept calls to the service via advice using AOP and check if you were permitted to call this method.
CALL --> Tx Advice --> Permission Advice --> Service -- > execute logic --> Commit/Rollback Tx in Tx Advice --> End CALL.
Now, I no longer need the Tx Advice because of the Transaction() attribute on my service methods.
However, how do I make it so that the transaction gets started before it makes it to the PermissionAdvice.
File : services.xml
<object id="BusinessLogicServiceBase" type="Winito.Server.Services.Impl.BusinessLogicService, Winito.Server">
<property name="ObjectPersistenceManager" ref="ObjectPersistenceManager" />
<property name="StatisticsStandingsManager" ref="StatisticsStandingsManager" />
....
</object>
<tx:attribute-driven/>
File: Dao.xml
<object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
<property name="ConfigSections" value="databaseSettings"/>
</object>
<!-- Database and NHibernate Configuration -->
<!-- SqlServer-2.0 -->
<db:provider id="DbProvider" provider="System.Data.SqlClient" connectionString="" />
<!-- NHibernate Configuration -->
<object id="NHibernateSessionFactory" type="Winito.Data.Base.NHibernate.CustomLocalSessionFactoryObject, Winito.Data.Base">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>Winito.Core</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<entry key="use_proxy_validator" value="false" />
<entry key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
<entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<entry key="connection.isolation" value="ReadCommitted" />
<!--<property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider,NHibernate.Caches.SysCache</property>-->
<!--<property name="cache.use_second_level_cache">true</property>-->
<entry key="command_timeout" value="340" />
<entry key="use_outer_join" value="true" />
<entry key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" />
</dictionary>
</property>
<!-- provides integation with Spring's declarative transaction management features -->
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
<!-- Transaction Management Strategy - local database transactions -->
<object id="transactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate30">
<property name="DbProvider" ref="DbProvider"/>
<property name="SessionFactory" ref="NHibernateSessionFactory"/>
</object>
<!-- Exception translation object post processor -->
<object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/>
Old Code:
<object id="BusinessLogicService" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target" ref="BusinessLogicServiceBase" />
<property name="interceptorNames">
<list>
<!-- <value>TimingAdvice</value> -->
<value>TransactionalAdvice</value>
<value>PermissionAdviceBusinessLogic</value>
</list>
</property>
</object>
In the Spring documentation on declarative transaction management, I read that you can specify an order element on the attribute-driven tag.
Something like
The value for order is used with the normal rules for aop advice ordering.