1.锁
1.1定义
锁是计算机协调多个进程或者线程并发访问某一资源的机制
在数据库中,除了传统的计算机资源(CPU、RAM、I/O等)的争用外,数据也是一种需要用户共享的资源,如何保证数据并发访问的一致性,有效性是数据库必须要解决的一个问题,冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言显得尤其重要也更加复杂
1.2锁的分类
- 从性能上,锁可以分为乐观锁和悲观锁
- 从对数据的操作类型上,锁可以分为读锁和写锁
读锁(共享锁):正对同一份数据,多个线程操作可以同时进行而不会相互影响
写锁(排它锁):当前写操作没有完成前,它会阻断其他线程的读锁和写锁
- 从对数据库的粒度上,分为表锁和行锁
表锁特点:
a)偏向myisam存储引擎
b)开销小,枷锁快,无思索,发生锁冲突的概率高,并发度低
c) myIsam在执行查询语句前会自动给涉及的表都加读锁,在执行增删改操作前会自动给涉及的表加死锁
1、对myISAM表的读操作(加读锁),不会阻断其他进程对同一表的读请求,但是会阻塞对同一表的写请求,只有当读锁释放后,才会执行其他进程的写操作
2、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写请求,只有当当前写锁释放后,才会执行其他进程的读写操作
简而言之,读锁会阻塞写,但是不会阻塞读,写锁会阻塞读和写
表锁一般在表数据迁移的时候使用
行锁特点:
a)偏向InnoDB存储引擎
b)开销大,加锁慢,会出现死锁,锁定粒度小,发生出土的概率低,并发度大
c)支持事务
2.事务
2.1定义
事务是由一组sql语句组成的逻辑处理单元,事务具有4个属性,通常称为事务的ACID属性
2.2事务的属性
原子性(Atomicity):事务是一个原子操作单元,其对数据的修改要么全都执行,要么全都不执行
一致性(Consistent):在事务开始和完成是,数据都必须保持一致状态,意味着所有相关的数据规则都必须应用🐟事务的修改,以保持数据的完整性,事务结束时,所有的内部数据结构(如B+tree索引或者双向链表)也都必须是正确的
隔离性(solation): 数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行,这意味着事务处理过程中的中间状态对外部是不可观的反之亦然
持久性(durable):事务完成之后,它对于数据的修改必须是永久性的,即使出现系统故障,也需要保持
2.3并发事务带来的问题
更新丢失:当两个或者多个事务选择同一行,基于最初选定的值进行更新时,由于事务都不知道其他事务的存在,就会发生前事务提交更新的值被后事务提交更新的值所覆盖
脏读:事务A读取到了事务B已经修改但是还未提交的数据,并且在这个数据上做了其它操作,此时如果B回滚就会导致A读取的值无效,这就是脏读,脏读不符合事务一致性的要求
不可重复读:事务A读取到了事务B已经修改并且提交的数据。比如:事务A在事务B更新数据前后进行两次对数据的读取。导致着两次对数据的读取结果不一致,这就是不可重复读,不可重复读不符合事务隔离性的要求
幻读: 事务A按照相同的筛选条件重新读取之前检索过的数据,却读取出了事务B新插入的满足筛选条件的数据,这种现象叫做幻读
总结:脏读是事务读取到了其他事务修改的数据
幻读是事务读取到了其他事务新增的数据
脏读、不可重复读、幻读其实都是数据库读一致性的问题必须由数据库提供一定的机制来解决
2.4事务的隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交 | 可能 | 可能 | 可能 |
读已提交 | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 可能 |
可串行化 | 不可能 | 不可能 | 不可能 |
数据库的事务隔离越严格,并发副作用越小,但是付出的代价越大。因为隔离实际上就是并行改串行,与并发是互相冲突的
数据库的事务和spring事务不一致时。采用的是spring设置的事务