diff --git a/tests/test_m11b2_single_tx.py b/tests/test_m11b2_single_tx.py index 9cfe4b3..e6f2749 100644 --- a/tests/test_m11b2_single_tx.py +++ b/tests/test_m11b2_single_tx.py @@ -254,13 +254,15 @@ class TestNormalWrite(TxCase): sql, params = upd[0] self.assertIn("UPDATE %s SET" % STATE_TABLE, sql) self.assertIn("entity_id=?", sql.replace("%s", "?")) + # 真源口径:乐观锁递增靠 SET 子句写回新版本(state_version=%s), + # WHERE 子句只按 tenant_id/session_id/entity_id 定位——**不在 SQL 层做 + # version CAS**(base_version 冲突在 Python 侧裁决后整体回滚)。 set_clause, where_clause = sql.split("WHERE", 1) - # 真源契约:state_version 由服务端在 SET 中写入新水位(3->4), - # 乐观锁的比较发生在事务内 SELECT 校验分支,绝不落进 WHERE 谓词 - # (落进 WHERE 会变成「靠 affected_rows 判冲突」的旧类式实现口径)。 - self.assertIn("state_version", set_clause) + self.assertIn("state_version=%s", set_clause) self.assertNotIn("state_version", where_clause) - self.assertEqual('{"hp": 2}', params[0]) + self.assertEqual('{"hp": 2}', params[0]) # state_json + self.assertEqual(4, params[1]) # state_version 写回 3+1 + self.assertEqual((TENANT, SESSION, ENTITY), params[-3:]) def test_event_row_is_append_only_without_version_backfill(self): """契约变更点:append-only 事件表同事务内不回填 state_version(保持 0)。""" @@ -408,8 +410,9 @@ class TestAtomicRollback(TxCase): self.assertEqual("ROLLBACK", self.kinds()[-1]) def test_failed_write_leaves_no_event_row(self): - # 真源乐观锁语义:base_version 只在实体行**已存在**时参与比较(新建分支无 - # 版本可校验)。故先预置 version=1 的行,再以 base_version=42 触发冲突回滚。 + # 真源语义:base_version 乐观锁只在「状态行已存在」时比对(tx_write._apply_state + # 的 if rows: 分支);无预置行会走 INSERT 分支不抛冲突。故先预置版本 1,再用 + # 过期的 base_version=42 触发 PBL-STATE-CONFLICT,才能验证「失败写入不留事件行」。 self.eng.seed_state(TENANT, SESSION, ENTITY, '{"hp":1}', state_version=1) before = self.counts() with self.assertRaises(RtxError): @@ -436,10 +439,10 @@ class TestIdempotency(TxCase): self.assertEqual(first["event_id"], second["event_id"]) self.assertEqual(first["seq"], second["seq"]) self.assertEqual(before, self.counts()) # 两表零增量 - # 首次写入走 insert 分支(无预置行)⇒ state_version=1;二次命中幂等 - # 直接 COMMIT 返回,绝不回写状态,故水位仍为 1(旧断言写 2 是钉在 - # 「夹具预置 version=1 再 update 到 2」的类式口径上,真源无该预置)。 - self.assertEqual(1, self.state_row()["state_version"]) + # 真源首写走 INSERT 分支 ⇒ state_version=1(旧类式夹具预置初值 1 才得到 2, + # 该预置口径已随 M11b-2a 迁移作废);二次写命中幂等,版本保持 1 不被改动。 + self.assertEqual(1, first["states"][0]["state_version"]) + self.assertEqual(1, self.state_row()["state_version"]) # 未被二次写改动 self.assertEqual(bcast, len(self.eng.broadcasts)) # 不重复广播 def test_derived_idem_key_is_stable_for_same_params(self):