【问题标题】:Phalcon DB block database in order to check it is possible to insert dataPhalcon DB 块数据库以检查是否可以插入数据
【发布时间】:2021-12-10 22:12:00
【问题描述】:

我正在使用Phalcon,并且我在 MySql 中有一个数据库。我在数据库中有三个表:

  • 用户:id、姓名、已售出
  • 公司:ID、名称、成本
  • 交易:id_company、id_user、成本

如果有足够的钱(已售出),用户必须进行交易。所以我必须这样做:

Step 1:
retrieve the sold of the user:
select sold
from user
where id='Charlie'

Step 2:
retrive the cost from the company:
select cost
from company
where id='Tango'

Step 3:
to check if the user has enough money:
if (sold-cost >= 0)
create the transaction
else
do not create the transaction.

我的问题是: 有没有办法阻止数据库以便在没有数据库更改的情况下执行三个步骤?

我想这样做:

lock db
step 1
step 2
step 3
unlock db

但我还没有找到解决办法。

【问题讨论】:

  • 如果您的意思是要进行一些数据库更改并且如果其中一个失败您回滚到原始状态或者如果满足某些要求您提交更改?那就是一笔交易read about it here
  • 是的,但我担心在同一时间(或在我解锁之前)另一个用户可能会使用更新行或删除行来更改表。即使在这种情况下,您是否可以进行 Phalcon 交易?
  • 是的,它可能会发生,但如果您同时有大量流量,就会发生这种情况。不,因为服务器是用来处理这类请求的。如果您对代码进行基准测试(没有 html 渲染),您会发现它发生在几毫秒内,因此除非您每秒收到数百个请求,否则您会没事的。测试是你的朋友,你可以模仿请求并检查发生了什么
  • 我使用 Phalcon 和 VueJs,所以默认情况下没有渲染。但我必须确保即使流量很大,交易也是安全的。我可以将 $this->db->e​​xecute 与 User::find() 和你让我通过的指南混合吗?我想所有这些方法都是安全的。
  • 事务仅用于提交,它不会冻结您的数据库,您的更改在您提交之前不会生效。因此混合executeUser::find() 不会相互影响,db 将在回滚后恢复到原始状态,之后您需要刷新结果

标签: php mysql phalcon phalcon-orm


【解决方案1】:

我不确定它是如何在 Phalcon 框架中实现的,但 PDO 扩展实现的事务在这里可能会有所帮助:

<?php
$pdo->beginTransaction();
$stmt = $pdo->prepare('select sold from user where id= ?');
$stmt->execute(['Charlie']);
$row = $stmt->fetch(PDO::FETCH_ASSOC);

$sold = $row['sold'];

$stmt = $pdo->prepare('select cost from company where id= ?');
$stmt->execute(['Tango']);
$row = $stmt->fetch(PDO::FETCH_ASSOC);

$cost = $row['cost'];

printf("Sold: %d, Cost: %d", $sold, $cost);

if ($sold >= $cost) {
    //reduse user sold
    $stmt = $pdo->prepare('update user set sold = sold - ? where id= ?;');
    $stmt->execute([$cost, 'Charlie']);

    // write transaction
    $stmt = $pdo->prepare('insert into transactions values (?, ?, ?);');
    $stmt->execute(['Charlie', 'Tango', $cost]);
    $pdo->commit();
} else {
    $pdo->rollBack();
}


$stmt = $pdo->prepare('select * from transactions');
$stmt->execute();
$transactions = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($transactions);

PHP PDO fiddle here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2021-05-24
    相关资源
    最近更新 更多