我已经得到了跨越某些表提交一些数据的一些客户端代码,简单来说就像这样:如何在更新后立即获取时间戳值?
- 客户端[ID,平衡,时间戳]
- ClientAssets [ID,由assetid,数量]
- ClientLog [ID,客户端Id,BalanceBefore,BalanceAfter]
当客户购买的资产,我做了下面的伪代码:
初学者ñ交易
- GetClientRow其中id = 1
- 拥有新资产的成本余额不足?是...
- 插入到客户资产...
- UpdateClient - >更新客户端设置余额= f_SumAssetsForClient(1)WHERE ID = 1和时间戳= TS从步骤1;
- GetClientRow当ID = 1
- 插入进ClientLog BalanceBefore =余额在步骤1中,BalanceAfter =余额在步骤5. COMMIT
在步骤4中,客户端行中1个更新语句中使用更新的一个函数'f_SumAssetsForClient',它为客户端汇总资产并返回这些资产的余额。同样在第4步,时间戳会自动更新。
我的问题是,当我在第5步再次调用GetClientRow时,有人可能更新了客户端余额,所以当我在步骤6中写入日志时,它不是真正的这一套步骤后的平衡。这将是这笔交易之外的另一笔写款之后的余额。
如果我在步骤4中调用UPDATE时可以从客户端行获取新更新的时间戳,那么我可以通过此步骤仅抓取客户端行,其中TS =新更新的TS。这可能吗?或者是我的设计有缺陷。我无法找到解决步骤5和步骤6之间的陈旧数据问题的方法。我觉得在表格设计中存在问题,但无法完全看到它。
听起来像你需要一个步骤3。5那就是'选择f_SumAssetsForClient(1)'然后存储该值,然后进行更新,然后写日志的价值观 - 你不应该有在所有处理时间戳 - 或做全过程作为存储过程 –
@MichaelCoxon哦,现在总是有意义的。基本上,在步骤4之后的任何时候,数据读取都是不可信的。但如果我在最终的UPDATE之前获取所有的值,这些值由时间戳检查保护,并确定提交或回滚,并使用它们来构建报告,那么它应该没问题。谢谢 :)。 –
那么,你在一个事务中运行这些语句,所以常用的方法是将第一选择中的锁升级到WRITE锁(似乎是MySQL中的SELECT ... FOR UPDATE),这会阻止其他会话从修改这个ID。 – dnoeth