在Phalcon中,提供事务使用的三种方式:
- 自定义事务(Manual Transactions)
- 单独的事务(Isolated Transactions)
- 隐含的事务(Implicit Transactions)
自定义事务(Manual Transactions)
在controller中的使用
use Phalcon\Mvc\Controller;
class PayController extends Controller
{
public function saveAction()
{
// 开启事务
$this->db->begin();
// db 为services中 di 注入的数据库对象key
// 当有多个数据库连接时,选择你需要的数据库操作对象key(不一定为db)
$pay = new Pay();
$pay->amount = 100;
$pay->created_at = time();
// 支付失败,回滚事务
if ($pay->save() === false) {
$this->db->rollback();
return;
}
$user = new User();
$user->money -= 100;
// 用户金额扣款失败,回滚事务
if ($user->save() === false) {
$this->db->rollback();
return;
}
// 提交事务
$this->db->commit();
}
}
其他方式
use Phalcon\Di;
// 可以通过Di容器获取数据库连接句柄
$db = Di::getDefault()->get('you_need_db_key');
$db->begin();
...
// 在Model中
$db = $this->getDI()->get('you_need_db_key')
$db->begin();
...
单独的事务(Isolated Transactions)
单独事务在一个新的连接中执行所有的SQL,虚拟外键检查和业务规则与主数据库连接是相互独立的。 这种事务需要一个事务管理器来全局的管理每一个事务,保证他们在请求结束前能正确的回滚或者提交。
use Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
use Phalcon\Mvc\Model\Transaction\Manager as TxManager;
try {
// 创建一个事物管理
$manager = new TxManager();
// 请求一个事务,默认是请求的 db 连接的事务
$transaction = $manager->get();
// 如果你有多个数据库连接,或者默认数据连接的key不是db,需要通过:
// $txManager->setDbService("db_name_key") 指定你需要的数据库
$pay = new Pay();
$pay->setTransaction($transaction);
$pay->amount = 100;
$pay->created_at = time();
if ($pay->save() === false) {
// rollback 会抛出一个 TxFailed 失败异常
$transaction->rollback("支付失败,事务回滚");
}
$user = new User();
$user->setTransaction($transaction);
$user->money -= 100;
if ($user->save() === false) {
$transaction->rollback("用户扣款失败,事务回滚");
}
// 提交事务
$transaction->commit();
} catch (TxFailed $e) {
// 捕获失败回滚的错误
echo "Failed, reason: ", $e->getMessage();
// 进行失败后的业务处理
...
}
隐含的事务(Implicit Transactions)
隐含的事务比较简单,可以直接通过orm直接使用。这里不做过多赘述
$user = new User();
$user->money -= 100;
$pay = new Pay();
$pay->amount = 100;
$pay->created_at = time();
if($pay->save() === false){
//失败处理
...
} else {
//成功处理
...
}