MySQL三大范式,事务,乐观锁悲观锁

  • MySQL事务的特性
    • mysql事务具有四大特性,分别是原子性,一致性,隔离性,持久性
      • 原子性,原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响,
      • 一致性,一致性是指事务必须使数据库从一个一致性状态换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态,举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加还得是1000,这就是事务的一致性。
      • 隔离性,隔离性是当多个用户并发访问数据库时,比如同时操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离,关于事务的隔离性数据库提供了多种隔离级别:未提交读,在此级别下脏读,幻读,不可重复读等问题都会出现。已提交读:此级别下解决了脏读的问题,存在幻读和 不可重复读(同时,这也是大多数数据库的默认事务隔离机制)。可重复读:此级别下解决了脏读和不可重复读的问题,但仍然存在幻读的问题(同时,这是mysql默认引擎InnoDB引擎的默认事务隔离级别)。可串行化:此级别下脏读,幻读以及不可重复读等问题都将不复存在,在次级别下每条操作命令都必须等到上一条命令执行完毕后才可以开始执行,此时我们的数据库可以看成是一个单线程的程序,数据是绝对安全的,但却严重影响程序的运行效率,只有数据安全性的要求大大高于运行的效率要求我们才使用该隔离级别。
      • 持久性,持久性是指一个事务一旦被提交了,那么对于数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作,例如我们在使用JDBC操作数据库的时候,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务已经正确提交,即使这时数据库出现了问题,也必须将我们的事务完全执行完成,否则的话就会造成我们虽然看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误,这是不允许的。
  • MySQL三大范式
    • 第一范式:数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是保证每一列的原子性;
    • 第二范式:在满足第一范式的前提下,要求表中的所有列,都必须依赖主键,而不能有任何一列与主键没有关系,也就是说一个表只描述一件事情
    • 第三范式:在满足第二范式的前提下,要求表中的每一列只与主键直接相关而不是间接相关,表中的每一列只能依赖于主键。
  • MySQL悲观锁与乐观锁的理解
    • 悲观锁和乐观锁是人们定义出来的概念,你可以理解为一种思想,是处理并发资源的常用手段,不要把他们与mysql中提供的锁机制(表锁,行锁,排他锁,共享锁)混为一谈。
      • 悲观锁:顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据,所以在整个数据处理过程中,需要将数据锁定。悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排它锁,select for update来实现悲观锁。悲观锁在并发控制上采取的是先上锁然后再处理数据的保守策略,虽然保证了数据处理的安全性,但也降低了效率
      • 乐观锁。顾名思义就是对数据的处理持乐观态度,乐观的认为数据一般情况下不会发生冲突,只有数据更新时,才会对数据是否冲突进行检测。如果发现冲突了,则返回错误信息给用户,让用户自己决定如何操作。乐观锁的实现不依靠数据库提供的锁机制,需要我们自己实现,实现方式一般是记录数据版本,一种是通过版本号,一种是通过时间戳,给表加一个版本号或时间戳的字段,读取数据时,将版本号一同读出,数据更新时,将版本号+1。当我们提交数据更新时,判断当前的版本号与第一次读取出来的版本号是否相等,如果相等,则给予更新,否则认为数据过期,拒绝更新,让用户重新操作。
      • 然后就是我们在乐观锁和悲观锁的选择上面,主要看下两者的区别以及使用场景。
        • 乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
        • 悲观锁依赖数据库锁,效率低,更新失败的概率比较低。随着互联网三高架构(高并发,高性能,高可用)的提出,悲观锁已经越来越少的被应用到生产环境中了,尤其是并发量比较大的业务场景。
  • 悲观锁和乐观锁的具体实现方式
    • 悲观锁的实现方式:悲观锁表明的是用户对他的每次操作都觉得会有其他用户同时进行操作,导致数据出现问题,此时悲观锁会在用户操作时将表锁住,让其他的用户不能对该条数据进行任何操作,select * from product where id=1 for update,使用了for update 之后就会自动将该条数据锁定,其他用户无法对该条数据进行查询,修改,删除的操作。注意事项:当查询条件是主键的时候,哪怕该主键所对应的记录不存在也不会进行锁表操作,相当于没有对表做任何操作。当查询条件不是主键且当前查询条件的记录不存在的时候,使用悲观锁会把整个表锁住(也就是表级锁)
    • 乐观锁的实现方式:乐观锁就是用户觉得他操作的数据在当前这个时刻不一定会有人和他同时进行操作,只需要在更新的时候判断一下记录的版本号和之前查询出的版本号是否一致即可,update product set count=10,version = version+1 where id=1 and version=1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值