gpt4 book ai didi

java - Spring 交易

转载 作者:行者123 更新时间:2023-11-30 02:48:29 27 4
gpt4 key购买 nike

我是 Spring 新手,有一个关于事务的问题。

我知道对于每个 http 请求都有一个 servlet 线程,它有自己的堆栈。据我所知,所有局部变量和方法都驻留在堆栈上。因此,如果我有一个方法 public void A();,那么 servlet 线程 A 和线程 B 的堆栈中都会有一个函数的副本。

现在,如果我用 @Transactional(propagation=Propagation.REQUIRED ,timeout=1,isolation=Isolation.READ_COMMITTED) 注释一个方法,那么我想知道以下几点:

  1. 每个线程A和线程B是否都有自己的堆栈并独立工作?

  2. 如果线程 A 正在更新某些内容而 B 正在读取某些内容,因为在不同的堆栈中,隔离会起作用吗?或者 B 会读取数据,但不包含有关线程 A 的任何信息?

我想通过图表了解这一点,以便我能够理解端到端的工作原理?

最佳答案

每个线程都有自己的堆栈,你就在这里。但他们没有方法的副本。方法只是一系列的操作。但他们在此方法内有变量的副本(局部变量)。

说到隔离级别,其实它与线程和堆栈无关。它指的是数据库隔离级别概念。 Spring 要求您的数据库提供用于数据库事务的级别。 PostreSQL 有一个很棒的 doc page解释事务隔离。

因此,这里询问线程如何相互查看并不完全正确,因为从数据的意义上来说,它们看到的是从数据库中获取的内容。数据库根据当前事务隔离级别返回数据。每个线程启动自己的事务,即它创建一个到数据库的新连接并告诉它启动一个新事务。

示例

要了解幕后发生的情况,这里有一个示例。假设你有这样的方法:

@Transactional
public Person getPerson(int id) {
Person person = em.find(Person.class, id);
return person;
}

以下是每行 Spring 引擎盖下发生的事情:

@Transactional
public Person getPerson(int id) {
// SQL sent to the database:
// Begin transaction

Person person = em.find(Person.class, id);
// SQL sent to the database:
// select p from person p where p.id = id
// the data from the database then gets converted to Java Person class

return person;
}
// after end of the method Spring automatically commits the transaction (not always, it depends on the `propagation` setting)
// SQL sent to the database:
// commit

请阅读深入解释事务隔离的 PostgreSQL 文档。 Java线程仅相应地接收数据。

关于java - Spring 交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39425137/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com