ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql 数据库事务

2022-05-11 17:33:54  阅读:201  来源: 互联网

标签:事务 缓存 行锁 lock 数据库 加锁 mysql 操作


事务:transaction 一系列sql语句的逻辑单元 类似于java 中的线程

事务特性:ACID

A:atomicity 原子性:操作的一致性

C:consistant 一致性: 数据的一致性

I:isolation 隔离性:和别的事务隔离

D:durable 持久性 

 

 多事务并发问题:

脏写:最后一个事务的更新覆盖了前面事务的更新;

脏读:读取到了为提交的事务,回滚后出现脏数据;

不可重复读:同一个事务中,相同查询语句查出来的数据不一致;

幻读:本事务对其他事务 更改后的语句(insert delete update)提交后,进行更新,会出现别的事务操作的数据;

 

解决办法1:数据库的隔离级别

  查询当前数据的隔离级别 show variables like 'tx_isolation';

  设置隔离级别:set tx_isolation='repeatable-read' 设置了只对本客户端生效。

  脏读 不可重复读 幻读 理解(操作是指 insert update delete)
读未提交(read-uncommitted) 可能发生 可能发生 可能发生 查询和操作公用相同的数据,不同事务更改数据后其他事务可通过查询看到。事务提交后全部更新到公共缓存
读已提交(read-committed) 解决 可能发生 可能发生 读取是当前事务中缓存的数据,操作数据在公共数据中操作 或者更改完数据同步到公共缓存中,操作完后更新本事务中的缓存数据。事务提交后全部更新到公共缓存
可重复读(repeatable-read) 解决       解决 可能发生 默认是本级别。读取和操作数据都在事务缓存中,如果操作不在本缓存中的数据 需要到公共缓存中,update 数据后 更新到当前缓存中,事务提交后全部更新到公共缓存
串行化(serializable) 解决         解决 解决 对本事务中的查询语句 在公共缓存中进行加锁,其他事务不可操作,保证数据的一致性。效率极低一般不采用

解决办法2 锁

  操作颗粒度区分:

  行锁:给数据行加锁。每次操作锁住一行数据。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高。InnoDB与MYISAM的最大不同有两点:InnoDB支持事务(TRANSACTION)InnoDB支持行级锁

  

  表锁:给整张表加锁,主要用于myisam 引擎,或者串行化中 无索引的条件字段 采用表锁。每次操作锁住整张表。开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低;一般用在整表数据迁移的场景。

  增加表锁

  lock table tablename read(write);

  查询当前加锁的表:show open tables;

  解锁:unlock tables;

  加行锁:sql语句后面 for update(排它锁 其余事务不能进行操作该语句查出来的数据) 若条件字段不是索引则锁全表

                    lock in share mode(共享锁) 

  读(select) 操作(insert update delete)   解释
当前session other session 当前session other session  
表写锁 阻塞 阻塞  
表读锁 报错 阻塞  
行锁 阻塞 InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁。
间隙锁(gap lock) 阻塞 就是锁两个值之间的间隙
for update(排它锁) 阻塞 同行锁,手动增加的行锁,其他事务可以增加排斥锁
lock in share mode(共享锁) 阻塞 同行锁,手动增加的行锁,其他事务可以增加共享锁
innodb 不加锁(非串行隔离级别) 加行锁  
myisam 加表读 加表写  

 

        

  那么间隙就有id为(3,10),(10,20),(20,正无穷)这三个区间,在Session_1下面执行updateaccountsetname='zhuge'whereid>8andid<18;,

  则其他Session没法在这个范围所包含的所有行记录(包括间隙行记录)以及行记录所在的间隙里插入或修改任何数据,即id在(3,20]区间都无法修改数据,注意最后那个20也是包含在内的。间隙锁是在可重复读隔离级别下才会生效。

  临键锁(Next-keyLocks):Next-KeyLocks是行锁与间隙锁的组合。像上面那个例子里的这个(3,20]的整个区间可以叫做临键锁。

 

  性能上区分:

  乐观锁:根据版本区分更新

  悲观锁:

  数据库的操作类型上区分 都属于悲观锁

  读锁:共享锁,S锁(Shared)):针对同一份数据,多个读操作可以同时进行而不会互相影响

  写锁:排它锁,X锁(eXclusive)):当前写操作没有完成前,它会阻断其他写锁和读锁

 

  操作:

  查询行锁的情况

       

  对各个状态量的说明如下:

  Innodb_row_lock_current_waits:当前正在等待锁定的数量

  Innodb_row_lock_time:从系统启动到现在锁定总时间长度

  Innodb_row_lock_time_avg:每次等待所花平均时间

  Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花时间

  Innodb_row_lock_waits:系统启动后到现在总共等待的次数

 

   

  select * from information_schema.INNODB_TRX; 查看所有事务详情;
  show PROCESSLIST; 查看连接的线程
  select * from information_schema.INNODB_LOCKS; 查看拥有锁 并且等待这把锁的事务
  select * from information_schema.INNODB_LOCK_WAITS; 查看等待的事务

  show engine innodb status \G; 查看锁日志

  结束进程:kill 线程id;

 

标签:事务,缓存,行锁,lock,数据库,加锁,mysql,操作
来源: https://www.cnblogs.com/xiatc/p/16257953.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有