开发中的那些坑

1、MySQL的tinyint类型是1个字节,默认范围是(-127,127)(默认是有符号数?)

2、在多线程编程中,由于多个线程共享同样的地址空间(也即共享同样的全局变量),常见的错误是:

每个线程从数据库读取数据,然后依据该数据进行后续的逻辑处理,然后把修改后的数据写回数据库,例如线程1和线程2从数据库表T中读取的F字段值都为1,两个线程的处理逻辑都是对F字段的值加1,然后把结果作为F字段的值写回数据库(其实就像一个投票的处理线程),结果两个线程跑完后,发现F字段的值为2,而不是期待的3;

问题分析:

其实这就是出现了不可重复读问题(事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。),因为假设线程1和线程2读取F值为1后,线程1先执行,把F值改为2,此时轮到线程2执行时,此时如果线程2再次读取F的值,会发现与开始读取的不一致,然而线程2的处理逻辑,是已经认为F的值没有变化,仍与之前的值一样,从而导致该问题;

正确做法:

(1)、使用数据库自身的运算更新其值,例如:

update T set F = F - 1 where id = 1;(该处id值举例为1)

(2)、再增加一个专用于更新F字段值的线程(或者进程),然后通过线程间通信(进程间通信),由线程1和线程2给专用线程(或进程)发送递增处理消息,由专用线程(或进程)进行处理;

(3)、在线程1和线程2开始读取F字段前,先加锁,直到更新完F字段后才释放锁(其实就是加了一把读写的排它锁,极度不推荐,因为加锁时间太长,对并发性能造成严重影响)。

猜你喜欢

转载自blog.csdn.net/scutjyj/article/details/79160310
今日推荐