spring.net事务属性仅适用于从外部调用的方法

时间:2011-01-15 13:59:09

标签: transactions aop spring.net

使用Spring.NET配置服务类。 DoWork完成两个应该在两个事务中运行的任务。但Spring.NET似乎没有调用任何事务性AOP行为。我必须使用Transaction属性注释DoWork(),但这会将两个Tasks包装在一个我不想要的事务中。 我该如何解决这个问题呢?

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 个答案:

答案 0 :(得分:2)

正如我所看到的here,Spring.NET正在使用基于接口的动态代理来完成其“AOP-ness”。基于接口的代理的工作方式与decorator pattern类似。 Task1Task2方法不是接口的一部分,因此Spring.NET无法修饰对这些方法的调用,因此无法应用任何行为。

Task1Task2更改为公开并将其添加到界面在您的方案中无效,因为DoWork调用this.Task1()this.Task2(),其中this代表具体对象,而不是AOP代理。

您的方案中唯一的解决方案是使用不同的AOP技术,在运行时基于基类的动态代理(我不知道Spring.NET是否允许这样做,它可以通过Unity Interception完成。 )或编译时编织(如PostSharp)。

答案 1 :(得分: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
  }
}