3

我有一个带有注释的方法的 POJO 类@Transactional

public class Pojo {

    @Transactional
    public void doInTransaction() {
        ...
    }
}

Spring 声明式事务管理基于 AOP,但我对此没有任何经验。我的问题是:是否有可能在单独调用(new Pojo).doInTransaction()时,Spring 会启动一个事务。

4

4 回答 4

3

Spring 声明式事务管理基于 APO,但我对此没有任何经验。

我建议您开始使用它,您将获得使用 AOP 使用事务建议的经验。一个好的起点就在这里

是否有可能在单独调用 (new Pojo).doInTransaction() 时,Spring 将启动一个事务。

不,您不能期望 Spring 知道您手动调用的 bean。但是,听起来您想要避免声明式事务管理并进行程序化事务管理。有一种方法可以使用 Spring 使用Transaction Template来做到这一点。那是你要找的吗?

于 2011-01-16T18:57:10.493 回答
2

这在某种程度上是可能的,但以一种麻烦的方式:您必须使用该AutowireCapableBeanFactory机制。

这是一个事务类作为示例

public interface FooBar{
    void fooIze(Object foo);
}

public class FooBarImpl implements FooBar{
    @Transactional
    @Override
    public void fooIze(final Object foo){
        // do stuff here
    }
}

下面是我们如何使用它:

public class FooService implements ApplicationContextAware{

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(
    final ApplicationContext applicationContext){
        this.applicationContext = applicationContext;
    }

    public void serviceMethod(){

        //declare variable as interface, initialize to implementation
        FooBar fooBar = new FooBarImpl();

        // try to use it, won't work, as it's not a proxy yet
        Object target = new Object[0];
        fooBar.fooIze(target); // no transaction

        // now let spring create the proxy and re-assign the variable
        // to the proxy:
        fooBar = // this is no longer an instance of FooBarImpl!!!
            (FooBar) applicationContext
                .getAutowireCapableBeanFactory()
                .applyBeanPostProcessorsAfterInitialization(fooBar,
                    "someBeanName");
        fooBar.fooIze(fooBar); // this time it should work

    }

}

这不是最佳做法。一方面,它使您的应用程序高度了解 Spring 框架,而且它违反了依赖注入原则。所以只有在没有其他方法的情况下才使用它!

于 2011-01-17T08:34:00.047 回答
1

是的,这可能的。Spring不需要使用动态代理@Transactional来工作。相反,您可以使用 AspectJ 提供的“真正的 AOP”。

有关详细信息,请参阅http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-aspectj

于 2011-06-10T12:41:48.353 回答
0

正如您所说,Spring通过Annotation处理事务的方式是使用AOP。AOP 位是使用动态代理实现的(请参阅doc

因此,为了做到这一点,您需要通过 spring 容器检索您的类的实例(此处为 Pojo),因为为了使其工作,Spring 将在您的 Pojo 上返​​回一个动态代理,该代理将自动用事务管理代码。

如果你只是做一个

Pojo p = new Pojo();
p.doInTransaction();

Spring 在这里没有任何作用,您的方法调用不会在事务中。

所以你需要做的是这样的

ApplicationContext springContext = ...;
Pojo p = (Pojo) springContext.getBean("your.pojo.id");
p.doInTransaction();

注意:这是一个示例,您应该更喜欢依赖注入而不是从上下文中手动检索 bean

通过这样做,并使用正确配置的 Spring 上下文,Spring 应该可以查看您的类以扫描事务注释并自动将您的 bean 包装到注释感知动态代理实例中。从你的观点来看,这并没有改变任何东西,你仍然会将你的对象转换为你自己的类,但是如果你尝试打印出你的 spring 上下文 Pojo bean 的类名,你会得到 Proxy$。 ..而不是你原来的班级名称。

无论如何看看这个链接:链接文本

于 2011-01-16T18:41:06.957 回答