做研究設計IRepository<T>
結構的最佳方式,我遇到了一個名爲「白板」(http://whiteboardchat.codeplex.com/)的項目,同時通過一些論壇爲NHProf
。nHibernate [TransactionAttribute]爲UoW衝突與存儲庫模式
我挖掘了一段時間的源代碼,發現MVC的一個非常有趣的屬性叫做TransactionAttribute
,定義如下: (我已經做了簡短的調整以適應我的IoC解決方案)
using System;
using System.Linq;
using Ninject;
namespace System.Web.Mvc
{
/// <summary>
/// This will allow ASP.NET MVC to apply Transactions to the controllers.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class TransactionAttribute : ActionFilterAttribute
{
[Inject]
public NHibernate.ISession Session
{
get;
set;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Session.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (Session.Transaction.IsActive)
{
if (filterContext.Exception == null)
{
Session.Flush();
Session.Transaction.Commit();
}
else
{
Session.Transaction.Rollback();
}
}
}
}
}
這真的很有趣;有用的,但是有關它的事情困擾我。當我使用NHProf
運行我的查詢時,它給了我關於'沒有正確使用交易'的警告,並建議我將所有查詢包含在Transaction
中。好吧,這是優秀和良好...
於是我去裝飾我Repository<T> : IRepository<T>
類這樣的...
public T Update(T instance)
{
using (var transaction = session.BeginTransaction())
{
// attempt to perform the given update
session.SaveOrUpdate(instance);
try
{
// commit the transaction to the database
transaction.Commit();
// update succeeded, so we'll return true
return instance;
}
catch
{
// restore the database to its previous state if we failed.
transaction.Rollback();
// update failed, so return a null object
return default(T);
}
}
}
這裏是我遇到的問題。
無論我讀什麼,常見做法是總是使用存儲庫添加到集合。然而TransactionAttribute
,這本身就被帶到了我的注意由Ayende Rahien的博客,誰是我所知的NHProf
的主要開發者之一,並在此白板項目工作的人之一,使得假設您在MVC控制器級執行存儲庫命令。
那它是哪一個呢?我現在完全困惑於我的交易邏輯應該採取最佳做法。我從字面上找到了相互矛盾的答案,並且在某些情況下來自同一個人。
這對我來說很有意義,但它並不能幫助NHPROF仍然給我提供有關事務管理的警告。你能看到我爲什麼仍然被認爲是'違反'的使用我發佈的屬性的任何理由嗎? – Ciel 2011-03-19 13:27:22
交易屬性看起來不錯。如果您將存儲庫更新(實例)方法更改爲「session.SaveOrUpdate(instance);」,您是否仍然在收到事務警告? – 2011-03-19 15:41:11