概述
我们知道,对于处理大量数据库事务的大型软件应用程序,实现并发管理机制是必不可少的,这样我们才能同时有效地处理多个数据库调用而不会丢失任何数据。
实现并发控制的方法之一是Java 持久性 API 提供的乐观锁定机制。
与悲观锁定相反,乐观锁定不会对数据库应用锁定,从而降低系统的隔离级别并增加软件的吞吐能力。此外,这不会像悲观锁定那样出现死锁。
它允许发生事务冲突并在提交事务时检测它们,然后我们可以根据用例处理流。
实现乐观锁定
乐观锁定的实现很简单。可以使用实体中的新属性版本来实现它(使用 @Version 对其进行批注)。尽管此属性有多种实现,但最有效和广泛使用的是一个简单的整数类型数字计数器类型版本,每次我们更新数据时,其值都会自动递增。我们还需要确保实体的状态不会因此而从缓存中获取。
让我们尝试了解版本属性的用法。
1) 投资者 1 和投资者 2 都将获取相同的数据,假设版本=1,
2)投资者1将首先保存,版本将自动更新为2(vesrion=版本+1)。
3)现在,当我们尝试保存 investor2 时,将运行类似于以下查询的查询
Update investor
Set version=2, firstName=’XYZ’
Where uuid=randomUuid
and version=1
4)现在我们知道,投资者1在保存时已经更新了该版本,因此在更新investor2时不会获取任何行,并且将为投资者2抛出乐观的锁定异常,从而防止投资者1的静默数据丢失。
乐观锁定异常的处理:
处理此异常的方法主要有两种:
1) 在 catch 块中,我们可以再次为 investor2 获取数据,然后尝试在可能的情况下更改数据,然后再次尝试保存数据。
2)第二个选项可能是我们只向用户显示一条消息,指出其他用户更新了数据或发生了错误,并要求用户再次更新数据。
因此,根据我们的用例,我们可以实现上述任一方法。
结论
虽然无法实现乐观锁定来处理所有类型的并发问题,但是否实现乐观锁定取决于具体情况。例如,它可以用于读取事务多于写入事务的情况。它可以用于我们不希望单个事务获取数据库锁的地方,或者实际上,我们可以承受数据丢失的地方。此外,就像在悲观锁定中一样,它不会对数据进行锁定,因此它可以用于我们在获取数据后将数据置于分离状态的地方,但与此同时,不用说,悲观锁定提供了更大的数据完整性。