SQL 银行竞争条件
SQL banking race condition
我正在用 NodeJS 和 SQL 数据库构建一个银行系统。我需要的两个主要功能是存款和取款。我想确保没有竞争条件。
例如:用户有 100 美元的余额,快速提取 100 美元两次,最后得到 -100 美元。
下面的查询可以有竞争条件吗?
update account set balance = balance - x where balance > x
如果这不能解决问题:
如果我使用 PostgreSQL,我的余额列上的检查约束是否足以消除所有竞争条件?
如果我使用 MySQL,我有哪些选择?
我很好奇在 PostgreSQL 和 MySQL
中实现此目的的不同方法是什么
因此,您可以执行以下操作:
- 在
withdraw()
函数中将自动提交设置为 false,即开始一个新事务。
- 使用
SELECT .. FOR UPDATE
读取记录
- 对值进行检查(即金额是否足以执行操作)
UPDATE
价值
- 结束交易
现在,当用户两次尝试快速取款时,其中一个调用将启动事务并发出 SELECT.. FOR UPDATE
调用,这将阻止另一个线程读取数据。只有在第一个线程完成后才会解除阻塞,即它将阻止 race condition
.
Here's MySQL 关于它的文档。
我正在用 NodeJS 和 SQL 数据库构建一个银行系统。我需要的两个主要功能是存款和取款。我想确保没有竞争条件。
例如:用户有 100 美元的余额,快速提取 100 美元两次,最后得到 -100 美元。
下面的查询可以有竞争条件吗?
update account set balance = balance - x where balance > x
如果这不能解决问题:
如果我使用 PostgreSQL,我的余额列上的检查约束是否足以消除所有竞争条件?
如果我使用 MySQL,我有哪些选择?
我很好奇在 PostgreSQL 和 MySQL
中实现此目的的不同方法是什么因此,您可以执行以下操作:
- 在
withdraw()
函数中将自动提交设置为 false,即开始一个新事务。 - 使用
SELECT .. FOR UPDATE
读取记录 - 对值进行检查(即金额是否足以执行操作)
UPDATE
价值- 结束交易
现在,当用户两次尝试快速取款时,其中一个调用将启动事务并发出 SELECT.. FOR UPDATE
调用,这将阻止另一个线程读取数据。只有在第一个线程完成后才会解除阻塞,即它将阻止 race condition
.
Here's MySQL 关于它的文档。