作者回复: 是的,赞。还有延伸内容,同样建议关注第15讲。
作者回复: 问题1,如果单元A成功,单元B失败,则面临一个选择。如果以努力成功为目标,则可以再次向单元B发送指令,有可能成功,这也是为什么要求操作具有幂等性。当然也可以直接撤销A操作,是A与B一样都是失败状态,这种就是失败回滚。 问题2,没有收到应答,其实也和问题1类似,重试争取成功,或者直接回滚。但这里面有个问题是,如果无论发送任何指令,单元B始终也没有返回,怎么办。这个时候基本上就是要人工干预了。当然,对于这种网络通讯故障也不是没有解决办法,有种协议叫做Paxos Commmit,可以极大缓解这个问题,我会在第15讲答疑篇详细介绍,你可以关注下。
作者回复: TCC可使用的手段更灵活,不限于数据库锁了。比如,可以增加一个“未冻结余额”字段,初始值和余额一样,一阶段时直接在这个字段上扣减金额,这样后发生的事务如果发现剩下的“未冻结余额”不够,就会返回失败,这样多事务就可以协同了。
作者回复: 谢谢你的肯定。这个专栏是跳出某个具体产品来讲原理,所以还是很挑听众的,能在每讲都有所收获,说明你也更厉害啊,点赞。
作者回复: 第一个问题,如果只实现“用主锁来控制事务的原子性,从锁保留指向主锁的指针”这个设计,那确实不一定要用MVCC。Percolator是一个工业实现,它要解决自己的业务需求,除了原子性还有隔离性要处理,使用了MVCC还可以解决读写冲突嘛。 第二个问题,我觉得是设计细节,采用其他形式应该也是可以的。
作者回复: 从公开资料看,也没有太特别的设计,就是把这个进程独立部署,这样不会与其他任务竞争资源。
作者回复: 我觉得2PC还不是共识算法,因为参与者并不是对一件事情(一个状态)投票,而是要让多个独立的状态要保持一致,且参与者并不了解这种一致性。可以参照15讲的Paxos Commit协议再体会下。
作者回复: 如果加了secondary锁,其他事务确实会读取到,是为了追溯事务状态,再决定读取哪个版本。而在异步线程或第一个读操作维护好状态后,就不再是私有版本了,所以我们说“通常其他事务不能读写”
作者回复: 是的,点赞。不过两者也可以联系起来看,我在第15讲会有详细说明。
作者回复: 理论上是不会的。GoldenDB是通过全局事务列表统一控制,数据节点(也就是单体数据库)基于日志实现回滚。TCC只要三个操作都正确实现,理论上也不会出现中间状态。