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

发布于 2024-10-12 07:35:52 字数 473 浏览 7 评论 0原文

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

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

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 can 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
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

这个俗人 2024-10-19 07:35:52

正如我在此处看到的,Spring.NET正在使用一个接口-基于动态代理来实现其“AOP 性”。基于接口的代理的工作方式类似于装饰器模式Task1Task2 方法不是接口的一部分,因此 Spring.NET 无法装饰对这些方法的调用,因此它无法应用任何行为。

Task1Task2 更改为 public 并将其添加到界面中对您的场景没有帮助,因为 DoWork 调用 this.Task1 ()this.Task2(),其中 this 代表具体对象,而不是 AOP 代理。

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

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).

感悟人生的甜 2024-10-19 07:35:52

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

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
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文