spring.net transaction attribute works only for methods called from outside
In have a service class configured with Spring.NET. DoWork accomplsihes two tasks which should run in two transactions. But Spring.NET seems not invoke any transactional AOP behaviour. I must annotate DoWork() with the Transaction attribute but this would wrap both Tasks in one transaction which I don't want. How ca开发者_如何学Cn I solve the problem?
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
}
}
As I see here, Spring.NET is using an interface-based dynamic proxying to accomplish its "AOP-ness". Interface based proxies work like decorator pattern. Task1
and Task2
methods are not parts of the interface, so Spring.NET can't decorate calls to these methods so it can't apply any behavior.
Changing Task1
and Task2
to public and adding it to the interface will not help either in your scenario, as DoWork
calls this.Task1()
and this.Task2()
, where this
will stand for concrete object, not an AOP proxy.
The only solution in your scenario is to use different AOP technique, either base class-based dynamic proxying at runtime (I don't know whether Spring.NET allows this, it can be done ie. with Unity Interception) or compile-time weaving (like PostSharp).
A. is correct with his observation.
However, I would suggest extracting the two tasks in two separate classes, which are injected on a class that has the DoWork()
routine.
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
}
}
精彩评论