雖然在處理程序中沒有引發異常,但我得到了NServiceBus重試消息X次的奇怪問題。有一些信息處理NHibernate會話和NSB環境事務。由於沒有錯誤發生,我不是100%確定的問題,因此不能真正決定做什麼。即使沒有異常,NServiceBus重試消息
我被配置NSB與城堡溫莎像這樣:
IWindsorContainer container = new WindsorContainer(new XmlInterpreter());
container.Install(new ContainerInstaller());
container.Install(new UnitOfWorkInstaller(AppDomain.CurrentDomain.BaseDirectory, Castle.Core.LifestyleType.Scoped));
container.Install(new FactoryInstaller(AppDomain.CurrentDomain.BaseDirectory));
container.Install(new RepositoryInstaller(AppDomain.CurrentDomain.BaseDirectory));
Configure.With()
.CastleWindsorBuilder(container)
.FileShareDataBus(Properties.Settings.Default.DataBusFileSharePath)
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.JsonSerializer();
的UnitOfWorkInstaller
寄存器工作(NHibernate會話)的單位像這樣:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var fromAssemblyDescriptor = AllTypes.FromAssemblyInDirectory(new AssemblyFilter(_installationPath));
container.Register(fromAssemblyDescriptor
.IncludeNonPublicTypes()
.Pick()
.If(t => t.GetInterfaces().Any(i => i == typeof(IUnitOfWork)) && t.Namespace.StartsWith("Magma"))
.WithService.AllInterfaces()
.Configure(con => con.LifeStyle.Is(_lifeStyleType).UsingFactoryMethod(k => k.Resolve<IUnitOfWorkFactory>().Create())));
}
因此,每個時間的消息到達時所有存儲庫都使用相同的工作單元。我讀過手動回滾當前事務結果的錯誤(我真的不知道爲什麼),我也知道NSB爲每個傳輸消息創建一個子容器,並且此子容器在處理消息後處理。問題是,當孩子容器佈置工作單元配置是這樣的:
public void Dispose()
{
if (!_isDisposed)
{
DiscardSession();
_isDisposed = true;
}
}
private void DiscardSession()
{
if (_transaction != null && _transaction.IsActive)
{
_transaction.Dispose();
}
if (Session != null)
{
Session.Dispose();
}
}
我的處理程序結構是這樣的:(該_unitOfWork作爲一個構造函數依賴通過)
public void Handle(<MessageType> message)
{
using (_unitOfWork)
{
try
{
// do stuff
_unitOfWork.Commit();
}
catch (Exception ex)
{
_unitOfWork.Rollback();
// rethrow so the message stays in the queue
throw;
}
}
}
我發現,如果我沒有提交工作單元(刷新會話並提交交易),我得到一個錯誤,表示郵件已重試超過最大重試次數bla bla bla ...
因此,它似乎與NHibernate會話和它的創建和處理方式,但是由於它是在工作單元內創建的,所以我無法真正使用會話工廠。我讀過我可以使用IMessageModule來創建和處理會話,但我不知道這是否正確,因爲我不明白是什麼導致了錯誤。
因此,要回顧:
我使用的工作範圍的單位,使所有的處理程序相依性將共享相同的實例(THX到子容器,BTW:我設置作爲臨時思考的工作單元,子容器將所有瞬態對象視爲該容器內的單例,但我看到工作單元未被共享,因此這就是爲什麼它的設置範圍)
我是將我的處理程序包裝在
using(_unitOfWork) { }
聲明中,以便在每次處理後處理工作單元。當下班的單位設置,NHibernate會話也設置
如果我不顯式調用
Commit
在_unitOfWork
,消息重試超出最大重試次數,然後拋出一個錯誤。
是什麼導致了這種行爲?而IMessageModule就是這個答案嗎?
查看錯誤隊列中的消息。消息頭中是否有異常消息? – stephenl 2012-04-12 00:30:01
@stephenl Nope,我看到的唯一信息是與' '相同的信息。它似乎與NHibernate有關,但我沒有任何與NHibernate的NSB集成。 –
2012-04-12 12:19:44