DaLei@home:~$

Django使用mysql的并发性问题的讨论



MySQl的事务等级

LEVEL DIRTY NOT REPEATABLE READ PHANTOM READ
read_uncommittd Y Y Y
read_committd N Y Y
repeatable-read N N Y
serializable N N N

Django对于MySQL事务等级的选择

  1. 如果项目并发量不高,可以选择使用serializable,只要使用事务就不会有任何问题,django代码也不用考虑锁的问题,有助于提升开发效率。

  2. 使用serializable的问题是效率的问题,在并发量比较高的时候不建议使用此级别

  3. 当并发较高时候repeatable-read是一个很好的选择

  4. 使用repeatable-read时,需要对需要更改的数据库选项加锁,增加代码的复杂度

Django加锁的方式

How to Manage Concurrency in Django Models

  • 上述文章讲述如何在django中加锁,通过两种方式,乐观锁和悲观锁

  • 悲观锁是基于select_for_update 进行的

  • 乐观锁是基于给数据加一个版本字段,通过在代码中操作进行的,详细信息可以参考上述链接

Django一些其他注意事项

  1. 低于serializable事务等级的代码一定需要加锁,否则会出现一些奇怪的问题,手动测试复现不了,只有通过压力测试Locust一类的工具才会复现

  2. get_or_create 函数不不要用于事务等级RR,具体原因参考官方解释

  3. Django lazy loading相关会缓存数据库变量的值,可以值会和数据库中的值不一致

  4. 其他持续更新中