read uncommited (读未提交):不作任何隔离,具备脏读,不可重读对,幻读的问题mysql
read committed (读提交):能够防止脏读,不能防止不可重复读和幻读的问题(用的最多)sql
repeated read(可重复读):能够防止脏读,不可重复读,不能防止幻读(mysql的默认隔离级别)数据库
serializable(串行化):数据库运行为串行,以上问题均可以防止,可是性能低django
下面的解释都用这个user表安全
name | age |
---|---|
jason | 38 |
1 a 开启事务 将jason的年龄改为 18岁,可是没有提交事务
2 b 开始事务 读取jason的年龄,发现是18岁。
上述的问题,
假设a事务回滚,b事务使用的数据就是错误的,就致使程序数据不正确。
1 a 开始事务 将jason的年龄改为18岁,可是提交了
2 b 开启事务 读取jason的年龄就能读取a事务修改后的jason年龄18岁。
1 a 开始事务 将jason的年龄改为18岁,可是提交了
2 b 开启事务 读取jason的年龄不能读取a事务修改后的jason年龄18岁。而是读取的是38岁
#概念和不可重读有点像,不可重复度是站在修改的基础上,而幻读是站在新增的基础上
1 a 开始事务 将全部的的年龄改为18岁
2 b 开始事务 新增一条数据数据name=tank,age=19,并且提交了。
3 a 从新查, 发现有一条数据 的age=19,这就是所谓的幻读。
select @@global.tx_isolation;
#修改配置文件my.ini
transaction-isolation=Read-Committed
#修改后必定要重启数据库
悲观锁的概念,他觉有人会修改我读的数据。那我就再查的时候,对数据进行锁定。别人只能查不能改
select age from user where id=1 for update;
好比 上面的查出来的 age =18
update age改为age = age+ 1
若是该次查询走了索引,那就是行锁,若是没有走索引就是表锁。
如何释放锁呢?结束事务(提交或者回滚)就释放了锁。
django中的orm是若是用悲观锁?
user.objects.select_for_update().filter(id=1).first()
乐观锁的本质不是锁。他是经过代码来实现锁的。他觉的别人不会修改的他的数据。他就读数据不会背别人修改。最后再修改该条数据,再where条件中添加,以前查出来的数据。以保证数据的安全性
select age from user where id=1 ;
好比 上面的查出来的 age =18
20
update age改为age = age+ 1 ====》19
乐观锁:
update age改为age = age+ 1 where age =18 and id =1 ====》19
若是我发现不是18,上面的影响行数是0
#若是是可重复读,上面的乐观锁无效,必须改为read committed
a update age改为age = age+ 1 ====》19 提交
b select age from user where id=1; --->18
update age改为age = age+ 1 where age =18 and id =1 ====》19 ---->数据已经被改