【发布时间】:2018-10-19 12:03:06
【问题描述】:
我刚刚发现,当我对 Postgresql 或 MariaDB 数据库使用乐观锁定时,我的应用程序的行为会有所不同,我想知道是否有人可以解释会发生什么以及如何使应用程序以与 MariaDB 相同的方式工作?我使用带有 InnoDB 引擎和默认设置的 Postgresl 10.5 和 MariaDB 10.3.10。我使用 Spring 框架版本 5.1.0 和 Hibernate 5.3.6。
所以我的代码如下所示:
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Bla {
@Id
@GeneratedValue
private long id;
@Version
private long version;
private int counter;
}
我也有这个实体的存储库和以下服务方法:
@Transactional
public int increment(long id) {
Bla bla = blaRepo.getOne(id);
bla.setCounter(bla.getCounter() + 1);
return bla.getCounter();
}
如果我在多个线程上调用此方法,我希望如果它们触及具有相同版本的实体,更新只会对其中一个成功。例如:如果我在一次运行中使用 Postgres db 启动 50 个线程,我会得到 3 个成功的调用并返回值 1、2、3,而其他 47 个调用失败并出现 ObjectOptimisticLockingFailureException,这是预期的行为 - 这就是我想要的要表现的应用程序。
但是,如果我切换到 MariaDB,则不会发生这种情况。所有 50 个线程都成功完成,并且我在多个线程中得到相同的响应值,就好像没有乐观锁一样。例如现在前 5 个线程返回 1,然后其中 20 个返回 2,其余 3 或 4 个。
为什么会这样?这没有任何意义 - 对于两个数据库,生成的查询都是
update bla set counter=?, version=? where id=? and version=?
但在 Postgresql 中会正确失败,而在 MariaDB 中会意外成功。
【问题讨论】:
-
你在使用 MyISAM 吗?
-
@LaurenzAlbe 不,我使用 InnoDb 作为 MariaDB 的引擎。
标签: postgresql hibernate jpa mariadb optimistic-locking