关于 business-logic-coder
面向 Rails 开发者的业务逻辑模式技能,指导如何组织一次性操作和具有生命周期的状态管理。内容涵盖 ActiveInteraction、AASM 及事务边界、隔离和死锁预防。
主要功能
- 01按需求选择业务逻辑模式
- 02ActiveInteraction 类型化操作
- 03AASM 状态转换管理
- 04事务边界与隔离级别建议
- 05死锁预防与事务反模式
适用场景
- 01实现注册、下单或支付操作
- 02管理订单或订阅生命周期
- 03将业务操作与状态转换组合
- 04设计多步数据库操作事务
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill business-logic-coder安装后在 Claude Code 中输入/business-logic-coder确认已加载。
附带文件references/aasm-patterns.mdreferences/active-interaction.md
详细介绍
业务逻辑模式
用于在 Rails 中编排结构化业务逻辑。
技能路由
| 需求 | 技能 | 使用场景 |
|---|---|---|
| 类型化操作 | active-interaction-coder | 创建业务操作、重构服务对象 |
| 状态机 | aasm-coder | 实现工作流、管理状态转换 |
何时使用
ActiveInteraction
用于操作——只发生一次的事情:
- 用户注册
- 下单
- 支付处理
- 数据导入
- 报告生成
# Example: One-time operation with typed inputs
outcome = Users::Create.run(email: email, name: name)
AASM
用于状态管理——具有生命周期的事情:
- 订单状态(待处理 → 已支付 → 已发货)
- 订阅状态(试用 → 活跃 → 已取消)
- 文档工作流(草稿 → 审核 → 已发布)
- 任务状态(待办 → 进行中 → 已完成)
# Example: Stateful entity with transitions
order.pay! # pending → paid
order.ship! # paid → shipped
组合模式
通常会结合使用——交互会触发状态变更:
module Orders
class Process < ActiveInteraction::Base
object :order, class: Order
def execute
order.process! # AASM transition
fulfill_order(order)
order
end
end
end
设置
# Gemfile
gem "active_interaction", "~> 5.3"
gem "aasm", "~> 5.5"
快速参考
ActiveInteraction:
.run- 返回结果(检查.valid?).run!- 失败时抛出异常compose- 调用嵌套交互
AASM:
.event!- 执行转换,否则抛出异常.event- 执行转换,否则返回 false.may_event?- 检查转换是否有效.aasm.events- 列出可用事件
事务边界
当业务逻辑涉及多步数据库操作时,请确保设置正确的事务边界。
原子操作
# PROBLEM: Partial failure leaves inconsistent state
def transfer_funds(from, to, amount)
from.update!(balance: from.balance - amount)
to.update!(balance: to.balance + amount) # May fail!
end
# SOLUTION: Transaction wrapper with locking
def transfer_funds(from, to, amount)
ActiveRecord::Base.transaction do
from.lock!
to.lock!
from.update!(balance: from.balance - amount)
to.update!(balance: to.balance + amount)
end
end
隔离级别
# Default: READ COMMITTED (each query sees latest committed data)
# REPEATABLE READ: All reads see same snapshot
ActiveRecord::Base.transaction(isolation: :repeatable_read) do
# Consistent reads for reports
end
# SERIALIZABLE: Full isolation (may cause serialization failures)
ActiveRecord::Base.transaction(isolation: :serializable) do
# Strictest isolation, retry on failure
end
死锁预防
规则:
- 按一致的顺序(按 ID 升序)锁定记录
- 保持事务简短
- 不要在事务中处理用户输入
- 不要在事务中调用外部 API
# PROBLEM: Deadlock risk (inconsistent lock order)
def swap_owners(item_a, item_b)
transaction do
item_a.lock! # Thread 1 locks A
item_b.lock! # Thread 2 locks B -> deadlock!
end
end
# SOLUTION: Consistent lock order
def swap_owners(item_a, item_b)
items = [item_a, item_b].sort_by(&:id)
transaction do
items.each(&:lock!)
# Safe: always locks lower ID first
end
end
事务反模式
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| 长事务 | 锁争用 | 拆分为更小的单元 |
| 在事务中调用 API | 超时会阻塞数据库 | 在事务外调用,然后再开启事务 |
| 在事务中处理用户输入 | 锁定时间不确定 | 先验证,最后开启事务 |
| 嵌套事务 | 保存点容易造成混淆 | 显式使用 requires_new: true |
嵌套事务
# PROBLEM: Inner rollback doesn't work as expected
transaction do
create_order!
transaction do # This is a savepoint, not new transaction
charge_card! # Failure rolls back to savepoint only
end
end
# SOLUTION: Explicit new transaction
transaction do
create_order!
transaction(requires_new: true) do
charge_card! # Failure rolls back only this block
end
end
相关技能
event-sourcing-coder- 记录状态转换产生的领域事件
评论
支持 Markdown