如何在Spring Boot中以毫秒级别设置使用Data JPA进行事务处理

huangapple go评论86阅读模式
英文:

How to set Spring boot with data JPA transactional in milliseconds

问题

以下是翻译好的内容:

我正在开发一个高性能且响应时间极为关键的应用程序,需要将 Spring Data JPA 事务的超时设置为毫秒。从一秒钟的粒度来控制对我来说是不太合适的。我已经验证无法通过 @transactional 注解 (org.springframework.transaction.annotation.Transactional) 或者通过 TransactionManager 接口来进行更改。这两种方式只允许将时间设置为秒。对我来说,在查询层面通过提示来进行更改也不是一个有效的解决方案。

如果不能以毫秒为单位进行设置,是否有人知道为什么 Spring Data JPA 存在这个限制?

示例代码:

package net.codejava;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ExpenseServiceImpl implements ExpenseService {

    @Autowired
    private ExpenseRepository repository;

    public void save(Expense expense) {
        repository.save(expense);
    }

    public void execTransaction1() {
        repository.deleteAll();
        repository.save(new Expense(1L, "早餐", 5));
        repository.save(new Expense(2L, "咖啡", 2));
        repository.save(new Expense(3L, "新 SSD 硬盘", 200));
        repository.save(new Expense(4L, "宝宝学费", 350));
        repository.save(new Expense(5L, "一些苹果", 5));
    }

    public void execTransaction2() {
        // repository.deleteAll();
        repository.save(new Expense(20L, "早餐", 5));
    }

    @Transactional(timeout = 1000) // 只能设置为秒!!
    public void logicaCoordinacion() {
        execTransaction1();

        execTransaction2();
    }

}
英文:

I am working on a high performance and highly response time critical application and need to timeout the spring data jpa transactions in milliseconds. It is not good for me to control it from a second. I have verified that it cannot be changed either through the @transactional annotation (org.springframework.transaction.annotation.Transactional) or through the TransactionManager interface. Both only allow exclusively to set the time in seconds. For me it is not a valid solution to change it at the level of queries with hint.

If it were not possible to do it in milliseconds, does anyone know why spring data jpa has this limitation?

Example code:

package net.codejava;
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional;

@Service
public class ExpenseServiceImpl implements ExpenseService {

@Autowired
private ExpenseRepository repository;

    public void save(Expense expense) {
    	repository.save(expense);
    }
    
    public void execTransaction1() {
       repository.deleteAll();
       repository.save(new Expense(1L, "breakfast", 5));
       repository.save(new Expense(2L, "coffee", 2));
       repository.save(new Expense(3L, "New SSD drive", 200));
       repository.save(new Expense(4L, "Tution for baby", 350));
       repository.save(new Expense(5L, "Some apples", 5));
    }
    
     
    public void execTransaction2() {
       // repository.deleteAll();
       repository.save(new Expense(20L, "breakfast", 5));
    }
    
    
    @Transactional(timeout = 1000) // Only in seconds !!
    public void logicaCoordinacion() {
    	execTransaction1();
    	
    	execTransaction2();
    }

}

答案1

得分: 2

我正在开发一个高性能且响应时间极关键的应用程序,需要以毫秒为单位设置 Spring Data JPA 事务的超时。

Spring不支持以毫秒为粒度设置@Transactional事务超时,因为这可能会不可靠。Spring无法保证垃圾收集器不会启动,导致在大堆上可能出现数百毫秒甚至数秒的情况。还有其他一些问题,Spring无法控制:时钟漂移,操作系统线程调度,CPU时钟频率调整等。

在实际情况下,@Transactional的3秒超时意味着超时将在大约3秒的时间点发生。由于我们使用秒为粒度,几毫秒的差异不会有实际影响。

Spring作为一个基于反射的重量级框架,再加上JPA作为重量级ORM层,对于需要毫秒级精度的系统来说可能并不是正确的选择。你可以尝试直接在数据库服务器端的JDBC驱动中设置此超时,这样可能会更可靠。

英文:

> I am working on a high performance and highly response time critical application and need to timeout the spring data jpa transactions in milliseconds.

The reason Spring does not allow @Transactional timeout with a millisecond granularity is because that would be unreliable. Spring can't guarantee that a garbage collector won't kicking in and that results in hundreds of milliseconds or even seconds on large heaps. There are also other issues that Spring has no control over: clock drift, OS thread scheduling, CPU clock frequency scaling, etc.

In practical terms a @Transactional timeout of 3s means that the timeout will happen somewhere around 3s mark. Since we are using seconds granularity, a few milliseconds later or earlier makes no practical difference.

The combination of Spring which is heavily based on reflection and JPA which is a heavyweight ORM layer doesn't feel like the right choice for a system that requires millisecond precision. You can try to set this timeout either directly in the JDBC driver on the database server side, perhaps it will be more reliable.

huangapple
  • 本文由 发表于 2020年9月12日 19:24:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63859799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定