MST

星途 面试题库

面试题:PostgreSQL常规锁加锁策略之共享锁与排他锁应用

在PostgreSQL中,共享锁(SHARE)和排他锁(EXCLUSIVE)是常见的锁类型。请描述在一个简单的银行转账场景(从账户A向账户B转账一定金额)中,如何合理使用共享锁和排他锁来保证数据的一致性和并发操作的正确性,同时说明使用这两种锁可能带来的性能影响。
16.8万 热度难度
数据库PostgreSQL

知识考点

AI 面试

面试题答案

一键面试

共享锁(SHARE)和排他锁(EXCLUSIVE)在银行转账场景中的使用

  1. 使用步骤
    • 开始事务:在PostgreSQL中,首先要开启一个事务,使用BEGIN语句。
    • 锁定账户A:对账户A使用排他锁(EXCLUSIVE),以防止其他事务在转账过程中修改账户A的余额。可以使用类似SELECT balance FROM accounts WHERE account_id = 'A' FOR UPDATE;语句,这里FOR UPDATE会对选定的行加排他锁。这样确保在当前事务处理账户A的余额时,其他事务不能同时修改该余额,保证数据一致性。
    • 读取账户A余额:在加锁后,读取账户A的当前余额。
    • 计算新余额:从账户A的余额中减去转账金额,得到新的余额。
    • 锁定账户B:同样对账户B使用排他锁(EXCLUSIVE),使用SELECT balance FROM accounts WHERE account_id = 'B' FOR UPDATE;语句,防止其他事务在转账过程中修改账户B的余额。
    • 读取账户B余额:加锁后读取账户B的当前余额。
    • 更新账户余额:将账户A的新余额更新到数据库中,然后将账户B的余额加上转账金额并更新。
    • 提交事务:使用COMMIT语句提交事务,释放锁。
  2. 为什么不使用共享锁(SHARE):共享锁允许其他事务同时读取数据,但不允许修改。在银行转账场景中,因为需要修改账户余额,共享锁无法满足需求,所以主要使用排他锁来保证数据修改的原子性和一致性。

使用这两种锁可能带来的性能影响

  1. 排他锁的性能影响
    • 并发度降低:排他锁会阻止其他事务对锁定资源的读写操作,这意味着如果有大量并发的转账请求,很多事务会因为等待排他锁而处于阻塞状态,降低了系统的并发处理能力。
    • 锁争用开销:多个事务竞争排他锁会增加锁争用的概率,数据库需要花费更多的时间和资源来处理锁的申请、授予和释放,从而增加系统开销。
  2. 共享锁的性能影响(虽然在此场景不适用,但从理论角度)
    • 脏读风险:如果使用共享锁读取账户余额,在读取后其他事务可能已经修改了余额,这可能导致数据不一致问题,虽然共享锁允许并发读,但对于银行转账这种需要精确一致性的场景不合适。
    • 性能提升假象:在一些场景下,如果错误地使用共享锁,可能表面上看起来并发度提高了,但实际上可能因为数据不一致需要回滚事务,最终导致整体性能下降。