read uncommitted :读未提交 ——— 引发问题 ———> 隐患:脏读
read committed :读已提交 ——— 引发问题 ———> 解决脏读隐患 隐患:不可重复读
repeatable read :可重复读 ——— 引发问题 ———> 解决脏读、不可重复读,隐患:幻读
serializable :可串行化 ——— 引发问题 ———> 解决以上所有隐患 隐患:影响性能,效率太低
隐患的解释:
脏读:A事务读取可B事务尚未提交的数据,如果B事务在A事务读取了尚未提交的数据后再次改了数据后提交 就会造成A事务的数据全部错误
不可重复读:A事务对某一数据进行读取后,进行其他的操作 ,此时B事务对该数据进行了修改并提交 ,A事务想校验该数据的真实性,再次读取该数据
造成前后两次读取数据的内容的不同 (侧重点在于内容的不一致)
幻读/虚读: A事务对某一数据进行读取后,进行其他的操作 ,此时B事务对该数据进行了增/删 并提交 ,A事务想校验该数据的真实性,再次读取该数据
造成前后两次读取数据的数量的不同 (侧重点在于数量的不一致)
关于丢失数据隐患的理解:
A,B事务同时对一组数据进行操作, A事务操作完之后数据提交, B事务操作后无论是提交还是回滚 都会使A事务提交的数据无效,造成更新丢失隐患
解决方案:
乐观锁:(从来不觉得会发生更新丢失隐患) 要求在表中额外添加一个字段(假设 versionv int )默认为0,当A事务对其数据进行修改后,要对其+1操作,
第二个事务想执行修改的时候,先查 version是否为先前查到的值,如果不是重新查询获得数据再修改提交
悲观锁:(认为更新丢失肯定会发生,采用霸王手段隔绝) 在查询时 手动添加 排它锁 select * from xxx for update
可以理解为两个人想喝水,只有一个杯子,先拿到杯子的先喝,喝完才会把杯子使用权交出来,后面其他事物想操作这个表,全部处于等待状态
读取多:使用乐观锁,提高吞吐量
修改多:使用悲观锁