Касательно Замка Автоматического управления транзакциями; У меня возникают трудности с получением операций для фактического сохранения в базе данных без очистки сеанса.
Я использую следующие компоненты
* NHibernate.dll v3.1.0.4000
* Castle.Core.dll v2.5.2.0
* Castle.Windsor.dll v2.5.3.0
* Castle.Facilities.NHibernateIntegration.dll v1.1.0.0
* Castle.Services.Transaction.dll v2.5.0.0
* Castle.Facilities.AutoTx.dll v2.5.1.0
Я очень внимательно следил за документацией Замка и не смог решить мою проблему.
Мое (веб-) приложение следует шаблону MVP. Ключевые части (транзакционной) услуги презентатора показаны ниже:
<Transactional()> _
Public Class CampusEditPresenter
Inherits BasePresenter(Of ICampusEditView)
Public Sub New(ByVal view As ICampusEditView)
MyBase.New(view)
End Sub
...
<Transaction(TransactionMode.Requires)> _
Public Overridable Sub Save() Implements ICampusEditPresenter.Save
' Simplified
Using session As ISession = _sessionManager.OpenSession()
Dim campus As New Campus()
campus.Code = _view.Code
campus.ShortDescription = _view.ShortDescription
campus.LongDescription = _view.LongDescription
campus.StartDate = _view.StartDate
campus.EndDate = _view.EndDate
session.Save(campus)
End Using
End Sub
End Class
Данный презентер-сервис зарегистрирован в инсталляторе:
container.Register( _
Component.For(Of CampusEditPresenter) _
.Interceptors(Of DebugLoggingInterceptor) _
.LifeStyle.Transient)
и разрешается видом (в основании):
Public Class BasePage(Of TPresenter)
Inherits Page
Protected _presenter As TPresenter
...
Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init
_presenter = _container.Resolve(Of TPresenter)(New With {Key .view = Me})
End Sub
...
End Class
Public Class CampusEdit
Inherits BasePage(Of CampusEditPresenter)
Implements ICampusEditView
...
Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSave.Click
_presenter.Save()
End Sub
...
End Class
Я зарегистрировал средства NHibernate и Transaction в файле конфигурации XML следующим образом:
<facility id="transaction" type="Castle.Facilities.AutoTx.TransactionFacility, Castle.Facilities.AutoTx" />
<facility id="nhibernate" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration" isWeb="true" configurationBuilder="[removed].AutoConfigurationBuilder, [removed]">
<factory id="nhibernate.factory">
<settings>
<item key="connection.driver_class">NHibernate.Driver.OracleClientDriver, NHibernate</item>
<item key="connection.connection_string">[removed]</item>
<item key="show_sql">false</item>
<item key="dialect">NHibernate.Dialect.Oracle10gDialect, NHibernate</item>
<item key="query.substitutions">true 1, false 0, yes 'Y', no 'N'</item>
<item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
<item key="current_session_context_class">web</item>
<item key="hbm2ddl.keywords">auto-quote</item>
</settings>
</factory>
</facility>
и я зарегистрировал модуль SessionWebModule Http в моем файле Web.config:
<httpModules>
<add name="NHibernateSessionWebModule" type="Castle.Facilities.NHibernateIntegration.Components.Web.SessionWebModule, Castle.Facilities.NHibernateIntegration"/>
...
</httpModules>
Есть идеи, почему это может не сработать?
Я могу заставить все работать, когда я а) создаю свои собственные транзакции из экземпляра ISession и фиксирую эти транзакции вручную, или если я б) использую AOP-механизм автоматического управления транзакциями и вручную очищаю экземпляр сеанса (хотя я не должен это нужно сделать вручную).
Я бы также подумал, что SessionWebModule IHttpModule (который следует шаблону open-session-per-request) вызовет сохранение моих сущностей, но, похоже, этого не происходит ...