【发布时间】:2022-01-10 13:08:55
【问题描述】:
当同一记录发生并发更新时,事务 1 能够更新,但根据 cockroach 数据库文档,事务 t2 应该在队列中,但事务 t2 立即失败。我们是否需要添加任何其他配置以使事务在队列中等待而不是立即引发重试事务错误。提前致谢
【问题讨论】:
标签: spring-boot spring-data-jpa isolation-level cockroachdb
当同一记录发生并发更新时,事务 1 能够更新,但根据 cockroach 数据库文档,事务 t2 应该在队列中,但事务 t2 立即失败。我们是否需要添加任何其他配置以使事务在队列中等待而不是立即引发重试事务错误。提前致谢
【问题讨论】:
标签: spring-boot spring-data-jpa isolation-level cockroachdb
是的,客户端应该处理事务重试错误。请注意,只要有可能,CockroachDB 将在内部auto-retry 一个事务而不通知客户端。 CockroachDB 只有在没有客户端干预的情况下无法自动解决错误时才会向客户端发送序列化错误。在这种情况下,cockroach 提供客户端工具来手动或自动重试 txn。请参阅文档here。
【讨论】:
sql.defaults.results_buffer.size? (cockroachlabs.com/docs/stable/…)
根据 CockroachDB 文档
CockroachDB 始终使用 SERIALIZABLE 隔离,这是最强的 SQL 标准定义的四个事务隔离级别中的一个 并且比后来开发的SNAPSHOT隔离级别更强。 SERIALIZABLE 隔离保证即使事务可能 并行执行,结果和执行一样 一次一个,没有任何并发。
我假设您将 Spring Boot 用于您的应用程序,将 Spring Data 用于数据库操作。
如果数据库中存在并发更新,那么在使用 sql 查询时最好使用SELECT FOR UPDATE。同样,@Locks 在 JPA 中也是如此。
@Lock(LockModeType.PESSIMISTIC_READ)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "3000")})
public Optional<Employee> findById(Long employeeId);
更多信息可以参考documentation。
【讨论】: