MySql教程

mysql 数据库事务

本文主要是介绍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;

 

这篇关于mysql 数据库事务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!