spring-boot - Spring JPA - 在多个事务中执行更新时事务不起作用
问题描述
@Transactional
似乎在我的应用程序中不起作用。
我试图在一个过程中更新一个实体,在另一个事务中,响应应该是具有最新值的实体。
所有的方法都是公开的和注释的,即使使用 REQUIRED_NEW 和 Isolation.READ_UNCOMMITTED,结果也一样。
执行 http://localhost:8888/example 启动。
调用 http://localhost:8888/example/1 我正在更新并返回:
{"id":1,"value":"OK"}
但是,在第一笔交易结束时,结果不正确:
{"id":1,"value":"NOT"}
是否org.springframework.data.jpa.repository.JpaRepository
适用于@Transaction
?
还是我错过了什么……?
示例: https ://github.com/jbrasileiro/stackoverflow-transaction
@EnableTransactionManagement
@EnableJpaRepositories("com.example.demo")
@EntityScan(basePackages = {"com.example.demo"})
@SpringBootApplication
public class DemoApplication {
public static void main(final String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Repository
public interface ExampleRepository extends JpaRepository<Example, Long> {}
@Service
public class ExampleService {
@Autowired
private ExampleRepository repository;
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public Example get(final Long id) {
return repository.findById(id).orElseThrow();
}
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public Example save() {
return repository.save(Example.builder()
.value("NOT OK")
.build());
}
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public Example update(final Long id) {
Example entity = repository.getOne(id);
entity.setValue("OK");
Example save = repository.save(entity);
System.err.println(save);
return save;
}
}
@RestController
@RequestMapping("/example")
public class ExampleController {
@Autowired
private ExampleService service;
@GetMapping
public ResponseEntity<Example> execute(){
Example entity = service.save();
Long id = entity.getId();
LocalDateTime envio = LocalDateTime.now();
LocalDateTime timeout = envio.plusSeconds(30);
do {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
System.err.println(service.get(id));
}
while (LocalDateTime.now().isBefore(timeout));
return ResponseEntity.ok(service.get(id));
}
@GetMapping("{id}")
public ResponseEntity<Example> update(@PathVariable(value = "id") final Long id){
return ResponseEntity.ok(service.update(id));
}
}
记录:
2020-09-17 16:04:44.659 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [com.example.demo.ExampleService.save]
2020-09-17 16:04:44.674 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2020-09-17 16:04:44.693 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2020-09-17 16:04:44.693 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [com.example.demo.ExampleService.save]
2020-09-17 16:04:49.700 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [com.example.demo.ExampleService.get]
2020-09-17 16:04:49.704 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:49.708 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:49.708 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [com.example.demo.ExampleService.get]
Example(id=1, value=NOT OK)
2020-09-17 16:04:51.639 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [com.example.demo.ExampleService.update]
2020-09-17 16:04:51.640 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.getOne]
2020-09-17 16:04:51.641 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.getOne]
2020-09-17 16:04:51.644 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2020-09-17 16:04:51.645 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
Example(id=1, value=OK)
2020-09-17 16:04:51.645 TRACE 660 --- [nio-8888-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [com.example.demo.ExampleService.update]
2020-09-17 16:04:54.715 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [com.example.demo.ExampleService.get]
2020-09-17 16:04:54.716 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:54.718 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:54.718 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [com.example.demo.ExampleService.get]
Example(id=1, value=NOT OK)
2020-09-17 16:04:59.722 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [com.example.demo.ExampleService.get]
2020-09-17 16:04:59.723 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:59.724 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2020-09-17 16:04:59.724 TRACE 660 --- [nio-8888-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [com.example.demo.ExampleService.get]
Example(id=1, value=NOT OK)
解决方案
推荐阅读
- reactjs - 如何使用 Redux 实现 React-navigation?
- r - 使用 R data.table 计算所有变量组合和 df 的不同计数
- appium - Android 模拟器 - 登录应用程序后无法执行操作
- python-3.x - python3 和 matplotlib:更改锚定文本的背景颜色
- python - CV2:尝试拍照时出现“[WARN:0] terminating async callback”
- java - AssertEquals 为两个相同的对象返回 false
- javascript - 在 forloop 中使用 .push 的函数不断地为数组赋值
- node.js - 在 AWS Lambda 上发出 https 请求
- alexa - Alexa 接受内置插槽类型的错误值
- mysql - 从外部表中按日期和 id 对 COUNT 进行分组