سؤال

ما هو أفضل نهج إدارة NHibernate المعاملات باستخدام Autofac ضمن تطبيقات الويب ؟

توجهي إلى الدورة

builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
       .ContainerScoped();

بالنسبة ITransaction, لدي وجدت مثال على مدونة جوجل, ولكن ذلك يعتمد على HttpContext.Current.Error عند تحديد ما إذا كان التراجع.

هل هناك حل أفضل ؟ وماذا نطاق NHibernate الصفقة يجب أن ؟

هل كانت مفيدة؟

المحلول

نشرت لي هذا منذ فترة:

http://groups.google.com/group/autofac/browse_thread/thread/f10badba5fe0d546/e64f2e757df94e61?lnk=gst&q=transaction#e64f2e757df94e61

تعديل بحيث اعتراضية لديه القدرة على تسجيل و [المعاملة] سمة يمكن أن تستخدم أيضا على فئة.

[global::System.AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class TransactionAttribute : Attribute
{
}


public class ServicesInterceptor : Castle.Core.Interceptor.IInterceptor
{
    private readonly ISession db;
    private ITransaction transaction = null;

    public ServicesInterceptor(ISession db)
    {
        this.db = db;
    }

    public void Intercept(IInvocation invocation)
    {
        ILog log = LogManager.GetLogger(string.Format("{0}.{1}", invocation.Method.DeclaringType.FullName, invocation.Method.Name));

        bool isTransactional = IsTransactional(invocation.Method);
        bool iAmTheFirst = false;

        if (transaction == null && isTransactional)
        {
            transaction = db.BeginTransaction();
            iAmTheFirst = true;
        }

        try
        {
            invocation.Proceed();

            if (iAmTheFirst)
            {
                iAmTheFirst = false;

                transaction.Commit();
                transaction = null;
            }
        }
        catch (Exception ex)
        {
            if (iAmTheFirst)
            {
                iAmTheFirst = false;

                transaction.Rollback();
                db.Clear();
                transaction = null;
            }

            log.Error(ex);
            throw ex;
        }
    }

    private bool IsTransactional(MethodInfo mi)
    {
        var atrClass = mi.DeclaringType.GetCustomAttributes(false);

        foreach (var a in atrClass)
            if (a is TransactionAttribute)
                return true;

        var atrMethod = mi.GetCustomAttributes(false);

        foreach (var a in atrMethod)
            if (a is TransactionAttribute)
                return true;

        return false;
    }
}

نصائح أخرى

عند استخدام autofac يمكنني استخدام نفس الحاوية راقب الطريقة ولكن بدلا من تمرير نفس الدورة إلى مستودع/DAO الكائنات أنا اجتياز UnitOfWork هذا هو حاوية راقب.وحدة العمل هذه في منشئ.

    private readonly ISession _session;
    private ITransaction _transaction;

    public UnitOfWork(ISession session)
    {
        _session = session;
        _transaction = session.BeginTransaction();
    }

و التصرف هو:

    public void Dispose()
    {
        try
        {
            if (_transaction != null &&
                            !_transaction.WasCommitted &&
                            !_transaction.WasRolledBack)
                _transaction.Commit();
            _transaction = null;
        }
        catch (Exception)
        {
            Rollback();
            throw;
        }

    }

أنا (ab)باستخدام حتمية التخلص من الاشياء في autofac من أجل إدارة هذا ، حسنا أنا نوع من مثل ذلك.

الشيء الآخر هو أنني في الأساس فقط استهداف ASPNet البيئة قرارا واعيا بأن الصفقة مرتبطة طلب ويب.حتى المعاملة في طلب ويب نمط.

لأن من أنني يمكن أن تفعل هذا الخطأ التعامل مع التعليمات البرمجية في IHttpModule:

    void context_Error(object sender, System.EventArgs e)
    {
        _containerProvider.RequestContainer.Resolve<IUnitOfWork>().Rollback();
    }

أنا لم أخذ نظرة على NHibernate.تحفر بشكل وثيق جدا ولكن أنا متأكد من أن هناك شيء ما هناك أن يفعل أكثر من هذا.

أنا عادة إدارة الصفقة نفسي..

public ActionResult Edit(Question q){
try {
 using (var t = repo.BeginTransaction()){
  repo.Save(q);
  t.Commit();
  return View();
 }
 catch (Exception e){
  ...
 }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top