网站的关键词库怎么做,ps制作手机app界面设计,wordpress sql文章,具有价值的常州做网站谢邀。首先我要指出问题中提出的各种概念非常混乱。简单梳理下#xff1a;早期数据库不论读取还是写入#xff0c;都用锁来实现。但是锁会带来性能的问题。人们尝试各种优化方案。写入和读取的优化方式不同。对于数据库写入操作#xff0c;没有特别好的办法#xff0c;因为…谢邀。首先我要指出问题中提出的各种概念非常混乱。简单梳理下早期数据库不论读取还是写入都用锁来实现。但是锁会带来性能的问题。人们尝试各种优化方案。写入和读取的优化方式不同。对于数据库写入操作没有特别好的办法因为无论如何要避免并发修改一个数据就得靠锁。不同的数据库对于写入操作都会加悲观锁(比如MySQL是X锁)。为了避免X锁带来的性能问题人们在合适的场合会选择用乐观锁来优化。有的数据库内建乐观锁但是有的没有(比如MySQL就没有)所以需要开发人员自己在数据表里加version列自己写业务代码实现。顺便提一句乐观锁并不一定总是比悲观锁性能表现更好这要看竞争的程度。如果数据访问竞争的非常厉害乐观锁只会让CPU和IO白白浪费而已。对于读取优化就是MVCC。现在主流的商业数据库都是基于MVCC如MySQL InnoDB和Postgres。MVCC的意思用简单的话讲就是对数据库的任何修改的提交都不会直接覆盖之前的数据而是产生一个新的版本与老版本共存使得读取时可以完全不加锁。这样读某一个数据时事务可以根据隔离级别选择要读取哪个版本的数据。过程中完全不需要加锁。这样实现两个隔离级别就非常容易Read Committed - 一个事务读取数据时总是读这个数据最近一次被commit的版本Repeatable Read - 一个事务读取数据时总是读取当前事务开始之前最后一次被commit的版本(所以底层实现时需要比较当前事务和数据被commit的版本号)。举个简单的例子一个事务A(txnId100)修改了数据X使得X1并且commit了另外一个事务B(txnId101)开始尝试读取X但是还X1。但B没有提交。第三个事务C(txnId102)修改了数据X使得X2。并且提交了事务B又一次读取了X。这时如果事务B是Read Committed。那么就读取X的最新commit的版本也就是X2如果事务B是Repeatable Read。那么读取的就是当前事务(txnId101)之前X的最新版本也就是X被txnId100提交的版本即X1。注意这里B不论是Read Committed还是Repeatable Read都不会被锁都能立刻拿到结果。这也就是MVCC存在的意义。在基于MVCC的数据库实现中根本就不需要出现Read Uncommitted这种情况。Read Uncommitted是早期数据库读写都基于锁进行实现的产物。在实际业务中Read Uncommitted毫无意义(如果真有意义你咋不去用NoSQL数据库)因此对于PostgresRead Committed和Read Uncommitted是一样的。对于Oracle压根就没有Read Uncommitted这个级别。所以从实际的角度出发我想所有人都忘记有“Read Uncommitted”这件事。MVCC并不是万灵药。大量的业务问题的关键点在于你在提交一个事务那一刹那你提交事务的所有修改依赖的读取是否都还有效。对于这种场景无论是Read Committed还是Repeatable Read都没有什么卵用。比如扣库存就是这样典型的业务场景。在这种场景下在MySQL InnoDB使用者会使用select ... for update手工加锁。或者干脆用Serializable隔离级别。在PostgresPostgres的Repeatable Read在提交时会提供一个“提交的修改的依赖是否被修改“的检测(好绕口但就是这个意思)。如果依赖已经被改掉了当前事务提交一定会失败。希望上面的简单回答可以让你重新对数据库、锁和隔离级别有所认识。如果没看懂也不奇怪问题本身的确非常复杂所以我专门写了一篇很长的文字来解释这个问题希望可以帮到你。数据库事务、隔离级别和锁www.jianshu.com