我正在寻找一种在从数据库中读取数据时实现数据完整性的方法(希望不使用太多资源),而不向模式中添加新字段。
完整性是指订单表中的订单金额和订单项目价格之和之间的完整性:
orders (id PK, description text, amount decimal)
order_items (id PK, order int ref orders.id, item int ref items, price decimal)
items (id PK, description text)
重要的是,订购物品的数量可以很大(几千件),并且每次显示完整的订购数量时都读取所有这些物品是不太实际的。但是当订单导出时,它应该是正确的,即使它可以在同一时刻更新。
例如:
用户A开始导出订单。
系统读取订单详细信息:从id=42的订单中选择*
用户b开始更新order 42,以便添加新的订单项并更新订单金额(在事务中,因此db中的数据是一致的)。
在满足导出请求的同时,系统继续执行第二个订单详细信息请求:从订单=42的订单项目中选择*
现在,导出中的数据不一致,因为订单总金额与通过合计订单项获得的金额不匹配。
是在导出时打开事务,还是在读取两个表之前锁定它们?
数据库是postgresql。
顺便说一句,这个问题应该很基本,所以为重复道歉,只是尽我所能寻找解决方案,但未能找到明确的一个。
最佳答案
你需要去拿一杯热茶和咖啡,然后阅读transaction isolation上的页面。
有两种选择。在第一种情况下,假设您锁定表以防止写入,然后,只要B在单个事务中执行更新,那么“read committed”就可以了。你不会在任何时候看到一半的更新。
在第二种情况下,“可重复读取”隔离级别将再次确保,只要B在单个事务中进行更新,那么一切都会好起来。数据库的“快照”将在其事务开始时被修复。
当然,可能无法更新已导出的订单(因为可能有人已经在尝试打包和发送我的原始订单)。不管怎样,我想订单/订购项目可能是一个很好的例子。
(回答编辑,因为radek的评论暗示我不清楚,如果有一件事你需要与并发问题,那么它是清楚的。希望是现在)