当前位置: 首页 > 面试题库 >

在Spring bean中启动新事务

东门焕
2023-03-14
问题内容

我们有:

@Transactional(propagation = Propagation.REQUIRED)
public class MyClass implementes MyInterface { ...

MyInterface有一个方法:go()

当go()执行时,我们开始一个新的事务,该事务在方法完成时进行提交/回滚-很好。

现在,在go()中,我们在MyClass中调用了具有的私有方法@Transactional(propagation = Propagation.REQUIRES_NEW。看来Spring会“忽略”
REQUIRES_NEW批注,并且不会启动新的事务。我相信这是因为Spring
AOP在接口级别(MyInterface)上运行,并且不会拦截对MyClass方法的任何调用。这样对吗?

有什么办法可以在go()事务中启动新事务?调用 另一个 具有配置为REQUIRES_NEW的事务的Spring托管Bean 的唯一方法是吗?

更新 :添加当客户端执行时,go()它们通过对接口而不是对类的引用来执行:

@Autowired
MyInterface impl;

impl.go();

问题答案:

从Spring参考2.5:

使用代理时,@Transactional只能将注释应用于具有公开可见性的方法。如果您对带有注释的受保护的,私有的或程序包可见的方法进行@Transactional注释,则不会引发任何错误,但是带注释的方法将不会显示配置的事务设置。

因此,Spring会忽略@Transactional非公共方法上的注释。

也,

在代理模式下(默认),将仅拦截通过代理传入的“外部”方法调用。这意味着“自调用”,即目标对象内的一种调用目标对象其他方法的方法,即使被调用的方法标有@Transactional!,也不会在运行时导致实际事务。

因此,即使您使用方法public,从同一个类的方法中调用它也不会启动新的事务。

您可以aspectj在事务设置中使用模式,以便将与事务相关的代码编织到类中,并且在运行时不创建代理。

有关更多详细信息,请参见参考文档。

另一种可能的方法是在类本身中获取类的Spring代理,然后在其上调用方法,而不是this

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class SomeService {

    @Autowired
    private ApplicationContext applicationContext;

    private SomeService  getSpringProxy() {
        return applicationContext.getBean(this.getClass());
    }

    private void doSomeAndThenMore() {
        // instead of
        // this.doSometingPublicly();
        // do the following to run in transaction
        getSpringProxy().doSometingPublicly();
    }

    public void doSometingPublicly() {
        //do some transactional stuff here
    }

}


 类似资料:
  • 问题内容: 警告: 注意:如果在事务期间调用此方法,则结果是实现定义的。 这就提出了一个问题: 如何在JDBC中开始事务? 很明显,如何结束事务,但不知道如何开始事务。 如果a 从事务内部开始,我们应该如何在事务外部调用以避免特定于实现的行为? 问题答案: 回答我自己的问题: JDBC连接以启用的自动提交模式开始,在该模式下,每个SQL语句都与事务隐式地划分了界限。 希望每个事务执行多个语句的用户

  • 问题内容: 当请求到达处理文件上传的servlet时,在该servlet中启动一个新线程是一个好主意,该线程将处理与上传的文件一起提供的另一段数据。我想以此同时处理这两项工作。 问题答案: 这不仅是一个坏主意,而且也行不通。原因如下:您的文件上传请求最终将命中方法。只要您使用此方法,容器就会保持连接打开。从该方法返回后(如果您决定在一个单独的线程中处理传入数据,则将提早完成),容器将假定您已完成请

  • 我用Inno Setup做了一个安装程序,在一些文件运行后我需要重启电脑,所以我用了这篇文章中的解决方案。 inno安装示例“CodePrepareToInstall”。iss运行良好,所以我使用了代码进行测试安装,但计算机重新启动后安装程序无法启动。 两个安装程序(inno demo和我的测试)都在“HKLM\Software\Microsoft\Windows\CurrentVersion\R

  • 更新: 我发现我将类A注入到扩展外部类的类C中,该类不受spring管理,如下所示: 这应该是交易失败的主要原因。 另一个问题:有没有办法让spring管理类A的事务,该类已经注入到非spring处理的anothor类中? 我正在用Spring Boot和Mybatis建立一个项目。 我有一个问题,其中一个服务类无法创建事务连接,也不会执行回滚。 我发现,如果我去掉B类中A类的注入,就像这样: 类

  • 我被告知下面的代码不能帮助我检查重复,因为在SELECT和UPDATE语句之前,结果可能不同。 这篇文章声称SELECT启动了一个事务:为什么我在从数据库视图中选择时得到了一个打开的事务? 所以呢?选择是否启动事务?

  • 在Ignite缓存中的事务性方法中,我们使用多线程方法。