Атрибут транзакции spring.net работает только для методов, вызываемых извне - PullRequest
0 голосов
/ 15 января 2011

В класс обслуживания настроен с помощью Spring.NET. DoWork выполняет две задачи, которые должны выполняться в две транзакции. Но Spring.NET, кажется, не вызывает никакого транзакционного поведения АОП. Я должен аннотировать DoWork () с атрибутом Transaction, но это обернет обе задачи в одну транзакцию, которая мне не нужна. Как я могу решить проблему?

IMyService service.DoWork();

public class MyServiceImpl : IMyService
{

public DoWork()
{
  Task1();
  Task2();
}

[Transaction(ReadOnly=false)]
protected void Task1()
{
  // do it
}

[Transaction(ReadOnly=false)]
protected void Task2()
{
  // do it
}
}

Ответы [ 2 ]

2 голосов
/ 20 января 2011

Как я вижу здесь , Spring.NET использует динамическое проксирование на основе интерфейса для выполнения своей "AOP-сущности".Прокси-интерфейс на основе интерфейса работает как шаблон декоратора .Методы Task1 и Task2 не являются частями интерфейса, поэтому Spring.NET не может декорировать вызовы этих методов, поэтому не может применять любое поведение.

Изменение Task1 и Task2public и добавление его в интерфейс не поможет ни в вашем сценарии, так как DoWork вызывает this.Task1() и this.Task2(), где this будет означать конкретный объект, а не прокси AOP.

Единственное решение в вашем сценарии - использовать другую технику AOP, либо динамическое проксирование на основе базового класса во время выполнения (я не знаю, позволяет ли это Spring.NET, это можно сделать, например, с Unity Interception ) или время компиляции (например, PostSharp ).

1 голос
/ 27 января 2011

A. правильно с его наблюдением.

Однако я бы предложил выделить две задачи в два отдельных класса, которые внедряются в класс с подпрограммой DoWork().

public class MyServiceImpl : IMyService
{
  // use property injection to set Task1 and Task2
  public DoWork()
  {
    Task1.Process();
    Task2.Process();
  }

}

public class Task1
{
  [Transaction(ReadOnly=false)]
  protected void Process()
  {
    // do it
  }
}

public class Task2
{
  [Transaction(ReadOnly=false)]
  protected void Process()
  {
    // do it
  }
}
...