开发者社区> 问答> 正文

MySQL数据库多线程并发怎么保证可靠

mysql采用默认事务隔离级别REPEATABLE-READ;
然后我分别执行以下内容:
1
2、使用jdbc访问数据库:
2
3、这时候打印结果,发现线程进入阻塞,一直卡在这里
3
也就是说我开启的另一个事务仍然能读取到数据,只是在最后执行executeUpdate的时候才被锁定不能执行
4、命令行执行commit
4
5、结果命令行操作被jdbc操作替换掉,数据改为4。
这不就是说REPEATABLE-READ仍然出现了丢失更新,而且没有行锁定吗?
事务与并发到底是什么区别,我在测试多线程执行以上jdbc操作时,发现最后得到的结果总是不对。例我开十个线程,每个都对数据+1,结果可能只加了5.所以在并发情况下怎么做才能保证数据的安全?

展开
收起
蛮大人123 2016-02-12 11:01:00 9027 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    被关于事务隔离级别错误信息误导,认为REPEATABLE-READ级别和SERIALIZABLE级别能解决丢失更新的问题,然而实际是不能的。
    因为mysql的select ... from table;语句 不管哪种隔离级别都是不会阻塞的
    在隔离级别下只有在更新数据时才会等待写锁(排它锁)的释放,所以我多个线程可以同时读取到number=3,基于此进行修改就必然会导致丢失更新。
    所以解决办法为程序中加入悲观锁 或 乐观锁 机制。
    悲观锁采用的是 select ... for update
    6
    这时事务B读取操作将无法执行,只有当事务A的commit完成,事务B才可以继续执行,相当于采用串行一个个执行。
    乐观锁常用的是版本控制或时间戳控制
    7

    这时候事务B发现version=1已经不存在了,因为事务A首先执行完更新了数据库,把version字段设为了2,这样就会导致该事务提交失败,需要我们在程序中判断异常情况下如何继续操作。
    以上就是我当前的理解,至于mysql本身支持的MVCC(多版本并发控制)还不知道怎么用,乐观锁的异常处理也不太清楚具体要怎么实现,可能是要根据具体的业务场景采用不同的处理手段吧。

    2019-07-17 18:41:11
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
DTCC 2022大会集锦《云原生一站式数据库技术与实践》 立即下载
阿里云瑶池数据库精要2022版 立即下载
2022 DTCC-阿里云一站式数据库上云最佳实践 立即下载

相关镜像