【发布时间】:2014-09-11 07:08:23
【问题描述】:
我有一个 Web 服务和几个后台运行的异步服务(用于长时间运行的数据收集过程),它们使用相同的 DAO 库和共享数据源。使用 Spring JDBC 模板实现的 DAO 库。 RDBMS 是 PostgreSQL。
当 Web 服务和异步服务通过 DAO 同时修改一个表中的相同行,结果数据不一致时,这种情况并不少见。
例如,我在一个实体中有“状态”字段,它可以取值:1 - 已付,2 - 未付。
有时我会遇到这样的情况:
- 事务 #1:Web 服务正在修改“状态”值 1 到 2 到 ID = 1 的行。
- 事务 #2:同时异步服务正在抓取一些 来自某些端点的数据并使用 ID 修改行的另一个字段 = 1。但是“state”字段仍然保持 1。它不知道“state”值在事务 #1 中从 1 更改为 2。
结果我的“状态”等于 1,尽管它必须是 2。它也有争议。有时异步服务会更改“状态”字段,而 Web 服务不知道此更改并再次造成数据混乱。当然,它不仅发生在 state 字段中。
我有两个选择:
- 使用悲观的 SELECT ... FOR UPDATE。
但它不适合我 因为 Web 服务经常从表中获取部分行。它 异步服务保持时不能等待很长时间 锁定,因为这里的性能至关重要。 - 使用乐观锁定。 “版本”字段等等。
但我不能只回滚 在乐观锁定失败的情况下发生变化,因为这会发生变化 必须合并。有时我不能只是重复操作,因为另一个系统中的原子操作不是 Spring jdbc 事务的一部分。
可能存在一些模式来处理诸如合并数据之类的情况?
谢谢,
伊万
【问题讨论】:
-
它不完全是重复的,因为这个问题是关于长时间运行的操作和同一数据库上的多个较短操作的问题。其他问题及其任何答案未解决这一点。
标签: java postgresql asynchronous concurrency spring-jdbc