Skip to content

Service ​

Service 编排业务:只调 Repository,不在 Service 里直接查库(禁止 Db::)。继承 core\base\Service,用基类提供的事务方法,不要手写 beginTransaction / commit / rollBack。

事务与 afterCommit ​

  • runInTransaction(Closure $fn):统一事务入口。
  • afterCommit(Closure $fn):在最外层事务真正提交后再执行;不在事务中则立即执行;事务回滚则丢弃。适合缓存失效、吊销 token 等「必须落库成功才做」的副作用。
php
use app\repository\user\UserRepository;
use core\auth\TokenVersion;
use core\base\Service;
use DI\Attribute\Inject;

class UserService extends Service
{
    #[Inject]
    protected UserRepository $userRepository;

    public function changePassword(int $userId, string $old, string $new): bool
    {
        // …校验旧密码…

        return $this->runInTransaction(function () use ($userId, $new): bool {
            $ok = $this->userRepository->update($userId, [
                'password' => password_hash($new, PASSWORD_DEFAULT),
            ]);
            // 事务提交后再吊销,避免密码未改成功就先失效
            $this->afterCommit(fn () => TokenVersion::bump($userId, 'user'));

            return $ok;
        });
    }
}

上例来自 app\service\user\UserService(依赖是 Repository;TokenVersion::bump 是核心辅助,不是另一个 Service)。AdminService 改密码后同样用 afterCommit 清会话缓存,保证事务提交后才吊销。

纪律 ​

  • 容器单例:实例属性只放注入的依赖,请求态放 support\Context。
  • 涉及资金等关键事务时,afterCommit 回调应自带 try/catch——回调抛错时库已经提交。

基于 MIT 许可发布