简体   繁体   中英

Spring JPA repository query update stuck / blocking

For the life of me, I'm not able to see what's wrong with the code causing the update query to get stuck. I tested the query directly on the database and it's fine.

I can confirm the application can connect to the database. The application can start fine. I can execute a findBy query just fine. It's just the update query that's stuck.

Repository class:

@Repository
public interface TestRepository extends CrudRepository<Test, String> {
    // Tried with @Modifying(flushAutomatically = true, clearAutomatically = true).  Still no luck.
    @Modifying
    @Query("UPDATE Test SET stopAllPayment = 'Y' WHERE location = 'london'")
    int stopAllPayment();
}

Service class

@Service
@RequiredArgsConstructor
public class StopPaymentService {
    private final TestRepository testRepository;

    @Transactional
    public void run() {

        // Stuck here.  Blocking.
        // In debug mode, the thread is waiting at SocketDispatcher.read0()
        testRepository.stopAllPayments();  
    }
}

Main class

@SpringBootApplication
@RequiredArgsConstructor
@EnableTransactionManagement
public class Main implements CommandLineRunner {
    private final StopPaymentService service;

    @Override
    public void run(String... args) throws Exception {
        service.run();
    }

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

application.yml

spring:
  datasource:
    url: jdbc:oracle:thin:@dbdev:1521/LT110
    username: user
    password: password
    driver-class-name: oracle.jdbc.OracleDriver
  jpa:
    hibernate:
      ddl-auto: none

pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath />
    </parent>

   
    <properties>
        <java.version>1.8</java.version>
    </properties>


    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>

        <!-- Oracle JDBC driver -->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>21.1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.4.5</version>
        </dependency>
    </dependencies>
</project>

When find method work and only the update hangs, the most likely explanation is a lock on the database.

Run the update, then check your database for blocking locks. The details of how to do that are database specific.

According to this article: https://howtodoinjava.com/spring-boot/command-line-runner-interface-example/

correct code for spring boot application, which implement CommandLineRunner, is the following:

@SpringBootApplication
public class SpringBootWebApplication extends SpringBootServletInitializer implements CommandLineRunner {

    @Autowired
    private StopPaymentService stopPaymentService;
 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringBootWebApplication.class);
    }
 
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
 
 
    @Override
    public void run(String... args) throws Exception {
        stopPaymentService.run();
        logger.info("Application Started !!");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM