黑神话悟空风格事务解读snapshot
第一幕:编程式事务の「五指山压顶」
场景:天庭财务部手动记账,悟空大闹数据库
// 手动挡事务(玉帝亲自执笔版)
public class 蟠桃园会计系统 {
public void 分发蟠桃(神仙 领桃人, int 数量) {
Connection conn = null;
try {
conn = 南天门数据源.getConnection();
conn.setAutoCommit(false); // 关闭自动提交(玉帝的朱砂笔悬停)
// 第一步:扣除库存
仓库DAO.扣除("九千年蟠桃", 数量);
if(仓库DAO.查询("六千年蟠桃") < 1000) {
throw new 天庭赤字异常("注意!注意!库存告急!");
}
// 第二步:登记领用人
台账DAO.登记(领桃人.仙箓编号(), 数量);
// 第三步:更新功德簿
功德系统.增加功德值(领桃人, 数量 * 100);
conn.commit(); // 玉帝盖章生效
} catch (Exception e) {
if(conn != null) conn.rollback(); // 太白金星撕毁账本
System.out.println("全体神仙注意!事务回滚:" + e.getMessage());
} finally {
if(conn != null) conn.close(); // 卷帘大将收拾案台
}
}
}
翻车名场面:
-
悟空拔毫毛变出100个分身,同时调用
分发蟠桃()
-
数据库连接泄漏导致线程池爆炸(天河水位暴涨)
-
忘记设置
setAutoCommit(false)
(自动给弼马温发了9999个蟠桃)
第二幕:注解式事务の「如来神掌」
场景:西天取经项目组使用Spring声明式事务
// 自动挡事务(如来加持版)
@Service
public class 取经报销服务 {
@Autowired
private 筋斗云DAO 筋斗云DAO;
@Transactional(
propagation = Propagation.REQUIRED, // 事务传播:佛法无边
isolation = Isolation.REPEATABLE_READ,// 隔离级别:八十一难互不干扰
rollbackFor = 紧箍咒异常.class
)
public void 报销路费(唐僧 领导, double 金额) {
// 第一步:登记报销
财务系统.提交申请(领导.袈裟编号(), 金额);
// 第二步:扣减预算
天庭财政部.扣减("取经专项", 金额);
// 第三步:发放铜钱
钱庄系统.转账(领导.通关文牒(), 金额);
// 触发回滚测试(八戒偷偷加的逻辑)
if(金额 > 10000) {
throw new 紧箍咒异常("超标!超标!念咒警告!");
}
}
}
技术亮点:
-
通过AOP代理实现(如来的无量神识覆盖整个方法)
-
默认只回滚RuntimeException(紧箍咒只对悟空生效)
-
事务传播机制像佛法加持范围(新事务/嵌套事务等)
第三幕:事务消息の「无间道」
场景:悟空击败妖怪后需要同步更新三界数据库
// 分布式事务(RocketMQ妖界特别版)
public class 除妖战绩服务 {
@Autowired
private RocketMQTemplate 筋斗云MQ;
public void 上报战绩(妖怪 目标) {
// 本地事务:更新天庭数据库
天兵系统.更新战绩(悟空.编号(), 目标.妖怪等级());
// 发送事务消息
Message<String> msg = MessageBuilder.withPayload(目标.妖怪编码())
.setHeader("击杀者", "齐天大圣")
.build();
筋斗云MQ.sendMessageInTransaction(
"战绩同步主题",
msg,
null
);
}
@RocketMQTransactionListener
class 战绩同步监听器 implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
try {
// 同步地府生死簿
阎王系统.勾销(目标.妖怪编码());
// 同步人间县志
人间史官.记载("某年某月,大圣除妖于白虎岭");
return RocketMQLocalTransactionState.COMMIT;
} catch (Exception e) {
return RocketMQLocalTransactionState.ROLLBACK;
}
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
// 兜底检查(土地公实地核查)
return 天兵系统.校验战绩(悟空.编号()) ?
COMMIT : ROLLBACK;
}
}
}
妖怪级难点:
-
地府服务器延迟高(奈何桥网络拥堵)
-
人间县志系统偶发400错误(书生写错字)
-
消息重复消费(牛头马面多次收到通知)
天庭技术白皮书
事务类型 | 使用场景 | 技术法宝 | 灵魂比喻 |
---|---|---|---|
编程式事务 | 精细控制事务边界 | JDBC原生API | 弼马温亲自喂天马 |
注解式事务 | 单服务简单业务流 | @Transactional | 如来一键启动佛法结界 |
事务消息 | 跨三界数据一致性 | RocketMQ事务消息 | 六耳猕猴保证消息必达 |
彩蛋:防坑Rap
Transactional 要小心 传播机制得搞清 Checked异常不回滚 rollbackFor要写明 事务消息虽巧妙 网络分区让人恼 监控埋点不能少 否则半夜on call到老!