Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 春季交易_Java_Spring_Spring Mvc_Spring Rest - Fatal编程技术网

Java 春季交易

Java 春季交易,java,spring,spring-mvc,spring-rest,Java,Spring,Spring Mvc,Spring Rest,我刚接触Spring,对交易有疑问 我知道每个http请求都有一个servlet线程,它有自己的堆栈。据我所知,所有局部变量和方法都驻留在堆栈上。因此,如果我有一个方法public void a()

我刚接触Spring,对交易有疑问

我知道每个http请求都有一个servlet线程,它有自己的堆栈。据我所知,所有局部变量和方法都驻留在堆栈上。因此,如果我有一个方法
public void a()
现在,如果我用
@Transactional(propagation=propagation.REQUIRED,timeout=1,isolation=isolation.READ\u COMMITTED)注释了一个方法
,那么我想知道以下几点:

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

  • 如果线程A正在更新某些内容,而B正在读取某些内容,因为在不同的堆栈中,隔离是否有效?或者B将读取数据,而不读取关于线程A的任何信息


  • 我想通过图表了解这一点,这样我就能理解端到端的工作原理了

    线程B只会在线程A的事务完成后看到线程A在数据库中所做的修改

    线程B仍然可能从数据库中读取某些内容,然后线程A更新数据库中的某些内容并提交,然后线程B覆盖线程A编写的内容


    为了避免这种情况,您需要对数据库使用某种类型的锁定,或者使用更严格的隔离级别(但这会带来高性能损失,因为数据库通常需要执行大量锁定以实现更严格的隔离级别)

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


    说到隔离级别,实际上它与线程和堆栈无关。它指的是数据库隔离级别。Spring要求数据库将该级别用于数据库事务。PostreSQL具有很好的事务隔离功能

    因此,这里不太适合询问线程如何看待彼此,因为在数据的意义上,它们看到了从数据库中获得的信息。数据库相应地将数据返回到当前事务隔离级别。每个线程启动自己的事务,即创建一个到数据库的新连接,并告诉它启动一个新事务

    例子 为了了解引擎盖下发生的事情,这里有一个例子。假设您有这样的方法:

    @Transactional
    public Person getPerson(int id) {
        Person person = em.find(Person.class, id);
        return person;
    }
    
    以下是每条生产线的弹簧罩下的情况:

    @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线程只接收相应的数据。

    简而言之:

  • B将读取数据,但不输出有关线程A的任何信息
  • 为什么会这样?在servlet环境中,通常有一个或多个servlet和类级别的所有数据,因此在doHttp方法之外共享相同的数据,servlet不是线程安全的

    当然,方法中的数据是线程安全的,因为每个方法都调用一个调用函数,并且都有一个线程用于服务方法请求,并且有自己的堆栈

    但是,如果您有两个并发方法调用,并且由于这个原因,在两个分离的线程中,事务将不相同,因为thrad local不相同,并且不共享相同的数据库内存。如果您考虑JPA,persistanceContext是存储在threadlocal中的一级缓存,这是很自然的。我的建议是使用更高级别的事务隔离来缓解可能出现的问题


    我希望它能帮助你

    太好了!!但是为了更清楚,你能告诉我线程A和线程B是如何知道彼此的事务的吗?它们在不同的堆栈中,对吗?我知道我是在问一些愚蠢的事情,但对我来说,这对概念的建立非常有帮助。@ BeeGupTA他们将使用不同的物理TCP连接到数据库服务器。“Spring请求数据库为数据库事务使用这个级别。”-谢谢这条重要的线:如果我有权获得你的AN,我肯定会这样做。你的回答说了过去10天我在网上搜索的所有内容。谢谢