Base solution for your next web application
Open Closed

Using SqlAzureExecutionStrategy (ABP and SQL Azure) #322


User avatar
0
etshei created

Hello everyone,

Recently, i started using Azure Plateform and i really like it. I deployed my ABP app in IIS (VM) and used the service provided for DB. Everything works fine but sometimes i get an error like "Database X on server Y is not currently available" with some "connection unsuccesseful" in the SQL Azure dashboard, and i found that i need to use the SqlAzureExecutionStrategy (link) in order to have a retry logic implementation, but there is a limitation with that, it doesn't support user initiated transactions (i get some errors when trying) that I think is caused by UOW implementation. I found this workaround (link) but i don't know how to make it work.

I really need some help in this.


5 Answer(s)
  • User Avatar
    0
    etshei created

    Anyone to help Do i need to use interceptors to resolve this problem? which method on which class?

  • User Avatar
    0
    hikalkan created
    Support Team

    You can disable transactions of UOW in ABP. See docs: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocUowOptions">http://www.aspnetboilerplate.com/Pages/ ... UowOptions</a> Just set

    Configuration.UnitOfWork.IsTransactional  = false;
    
  • User Avatar
    0
    mikaelgra created

    Hello. I also have this issue and would like a solution that doesn't simply just disable the transaction feature. Rather, it should disable to retry feature provided by the execution strategy of the DbContext in cases the transaction is not needed (which is the case for most 'get' methods).

    I feel that this is definitely possible to implement, but it would require overriding the EfUnitOfWork from Abp.EntityFramework with my own class. Is this possible in ABP?

    Something (roughly) like this would probably solve the issue:

    public class MySpecialUnitOfWork : EfUnitOfWork
       {
          public MySpecialUnitOfWork ( IIocResolver iocResolver, IUnitOfWorkDefaultOptions defaultOptions )
             : base( iocResolver, defaultOptions )
          {
    
          }
    
          protected override void BeginUow()
          {
             if ( Options.IsTransactional == true )
             {
                MySpecialConfiguration.SuspendExecutionStrategy = true;
             }
    
             base.BeginUow();
          }
    
          protected override void CompleteUow()
          {
             base.CompleteUow();
    
             if ( CurrentTransaction != null )
             {
                MySpecialConfiguration.SuspendExecutionStrategy = false;
             }
          }
    
          protected async override Task CompleteUowAsync()
          {
             await base.CompleteUowAsync();
    
             if ( CurrentTransaction != null )
             {
                MySpecialConfiguration.SuspendExecutionStrategy = false;
             }
          }
    
          protected override void DisposeUow()
          {
             base.DisposeUow();
    
             if ( CurrentTransaction != null )
             {
                MySpecialConfiguration.SuspendExecutionStrategy = false;
             }
          }
       }
    

    But how do I override the EfUnitOfWork registration with this?

  • User Avatar
    0
    hikalkan created
    Support Team

    Can you try this: In your EF project module, in PreInitialize;

    IocManager.Register<IUnitOfWork, MySpecialUnitOfWork>

    This configures to use MySpecialUnitOfWork instead of EfUnitOfWork.

  • User Avatar
    0
    mikaelgra created

    Hello, thank you for your answer.

    I am worried this causes a bug in the framework. If I do this, then I get the following warning everytime UOW is used:

    "Outer UOW key could not found in UnitOfWorkDictionary!"

    I registered it like this:

    IocManager.Register<IUnitOfWork, MySpecialUnitOfWork>( DependencyLifeStyle.Transient );
    

    Any suggestions?