asimlqt / transact
PHP事务库
Requires
- php: >=5.6.0
This package is not auto-updated.
Last update: 2024-09-15 05:02:34 UTC
README
Transact 是一个PHP事务库,类似于数据库事务的方式,但用于PHP代码。
其目的是能够执行多个动作,这些动作可能依赖于之前动作的成功完成才能执行下一个动作,并在失败的情况下,希望回滚到原始状态。
安装
使用以下composer命令安装
composer require asimlqt/transact
示例
以下示例创建了3个简单的动作,在execute
和revert
方法中输出一些文本。此示例将在整个README中引用,只有更改将被列出。
use Asimlqt\Transact\TransactionManager; use Asimlqt\Transact\Action; use Asimlqt\Transact\TransactionFailedException; $transactionManager = new TransactionManager(); class Action1 extends Action { public function execute() { echo "Action1 execute\n"; } public function revert() { echo "Action1 revert\n"; } } class Action2 extends Action { public function execute() { echo "Action2 execute\n"; } public function revert() { echo "Action2 revert\n"; } } class Action3 extends Action { public function execute() { echo "Action3 execute\n"; } public function revert() { echo "Action3 revert\n"; } } $transactionManager ->addAction(new Action1()) ->addAction(new Action2()) ->addAction(new Action3()); try { $transactionManager->execute(); echo "Transaction completed successfully\n"; } catch (TransactionFailedException $e) { echo $e->getMessage() . "\n"; }
程序输出
Action1 execute
Action2 execute
Action3 execute
Transaction completed successfully
执行顺序
动作将按照添加的顺序执行。当发生错误时(例如抛出异常),将按照相反的顺序调用revert
方法。最后成功动作的revert
方法将被首先调用,然后是上一个动作,以此类推,直到第一个动作。
例如,如果第三个动作抛出异常,则将调用Action2
的revert
方法,然后调用Action1
的revert
方法。
class Action3 extends Action { public function execute() { echo "Action3 execute\n"; throw new Exception(); } public function revert() { echo "Action3 revert\n"; } }
输出将是
Action1 execute
Action2 execute
Action3 execute
Action2 revert
Action1 revert
Transaction failed
你可能已经注意到,Action3
的执行方法抛出异常,为什么没有调用Action3
的回滚方法?这是因为每个动作应该只执行一个任务,如果动作因为无法完成任务而抛出异常,那么就没有东西可以回滚了!
向动作传递数据
通常,动作需要一些数据来执行其任务,为此可以使用Intent
对象,它是一个简单的数组包装器。它只有两个方法:get
和set
。这将在调用执行方法之前自动注入到动作中。
$intent = new Asimlqt\Transact\Intent(); $intent->set("user", $user); $transactionManager->setIntent($intent);
然后在动作中,你可以使用以下方式检索用户
public function execute() { $user = $this->getIntent()->get("user"); ... }
请注意,相同的intent对象将转发给所有动作,因此有可能覆盖数据。如果需要从一个动作向另一个动作传递数据,这也可以是有用的。
重试策略
如果动作由于某些外部因素无法完成任务,你可能想再次尝试执行该动作,例如执行API请求。可以为execute
和revert
指定重试策略。它们是针对特定动作的,因此只能为单个动作指定重试策略,或者为不同的动作指定不同的策略。以下是一些当前可用的策略:
RetryNone
这是默认策略,如果你没有明确指定,则不执行任何重试。
RetryOnce
这将立即尝试再次执行动作,然后再将其标记为失败。
RetryNumTimes
这将重复尝试执行动作指定次数。
RetryAfter
这将延迟指定的微秒数后再次尝试请求。
你需要在将动作对象添加到事务管理器之前设置这些策略。
$action1 = new Action1(); $action1->setExecuteRetryPolicy(new Asimlqt\Transact\Retry\RetryOnce()); $transactionManager->addAction($action1);