2011-01-15 3 views
0

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

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 
} 
} 
+0

, связанный с [этим похожим вопросом] (http://stackoverflow.com/questions/4280143/asp-net-mvc-controller-declarative-aop-with-spring-net/4346791#4346791) Я ответил месяц назад. Ответ А. верный, и связанный ответ может дать вам дополнительную справочную информацию. – Marijn

ответ

2

Как я вижу here, Spring.NET использует интерфейсную на основе динамического прокси для выполнения своей «АОП-Несс». Интерфейсные прокси работают как decorator pattern. Task1 и Task2 методы не являются частями интерфейса, поэтому Spring.NET не может украшать вызовы этих методов, поэтому он не может применять какое-либо поведение.

Изменение Task1 и Task2 общественности и добавление его к интерфейсу не помогут либо в вашем сценарии, так как DoWork звонки this.Task1() и this.Task2(), где this будет стоять для конкретного объекта, а не АОП прокси.

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

+0

Это решение, но не решение _only_. Кроме того, похоже, что Spring.net поддерживает прокси-сервер, основанный на наследовании, от версии 1.3.1, что может помочь. – Marijn

1

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

Однако я бы предложил извлечь две задачи в двух отдельных классах, которые вводятся в класс, который имеет процедуру 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 
    } 
} 
Смежные вопросы