Spring Boot,无法从插入另一个线程的数据库中获取更新的数据

时间:2019-03-01 10:39:10

标签: spring-boot jpa dirtyread

我正在使用Spring Boot 2.1.2和JpaRepository。在同时使用异步方法更新db中的某些数据时,方法尝试访问更新的数据时,另一方法则同时进行。但是,在更新异步方法后,我无法在第二种方法中获取更新的数据。我附上配置和下面的代码。有人可以帮我解决这个问题。

属性文件

# Application running port
server.port=8000

# Application running port
server.servlet.contextPath=/test

#DB config
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/db_name?useSSL=false
spring.datasource.username=root
spring.datasource.password=root

# Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000

# JPA specific configs
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.default_schema=littracker
spring.jpa.properties.hibernate.search.autoregister_listeners=false
spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider

# to enable transaction
logging.level.org.springframework.transaction.interceptor=TRACE
# Log files
logging.file=logs/applog.log
logging.level.org.springframework.web: ERROR
logging.level.org.hibernate: ERROR

模型类

package com.app.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_test")
public class Test implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id; 

    @Column(name = "name",nullable = false)
    private String name;

    @Column(name = "count",nullable = false)
    private Integer count;

    @Column(name = "active",nullable = false)
    private Integer active;

    public Test(String name, Integer count, Integer active) {
        super();
        this.name = name;
        this.count = count;
        this.active = active;
    }

    public Integer getId() {
        return id;
    }

    public Test() {
        super();
        // TODO Auto-generated constructor stub
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Integer getActive() {
        return active;
    }

    public void setActive(Integer active) {
        this.active = active;
    }



}

存储库

package com.app.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.app.model.Test;

public interface TestRepo extends JpaRepository<Test, Integer>{

    Test findByActiveAndId(int i, int j);

}

服务界面

package com.app.service;

public interface AsyncService {
    void testSave();
}

服务实施

package com.app.serviceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import com.app.model.Test;
import com.app.repository.TestRepo;
import com.app.service.AsyncService;

@Service("AsyncService")
@EnableAsync(proxyTargetClass = true)
public class AsyncServiceImpl implements AsyncService {


    @Autowired
    private TestRepo testRepo;


    @Override
    @Async
    public void testSave() {
        Test test = new Test();
        for (int i = 0; i < 1000; i++) {
            try {
                Thread.sleep(3000);
                test.setId(1);
                test.setActive(1);
                test.setCount(i);
                test.setName("name" + i);
                testRepo.saveAndFlush(test);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }

}

控制器

package com.app.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import com.app.model.Test;
import com.app.repository.TestRepo;
import com.app.service.AsyncService;

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    AsyncService asyncService;

    @Autowired
    TestRepo testrepo;

    @GetMapping()
    public String addUser() {
        asyncService.testSave();
        boolean flag = true;
        int count = 0;
        Test test = null;

        do {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            test = testrepo.findByActiveAndId(1, 1);
            System.out.println("-from DB---" + test.getCount() + "----");
            if (test.getCount() == 1000)
                flag = false;
            if (count == 1100) {
                System.out.println("Time exceeded ==== " + count);
                flag = false;
            }
            count++;
        } while (flag);

        return "success"
    }

}

0 个答案:

没有答案