mysql的事务

一、什么是事务?

  保证数据的一致性。例如:A向B转账500,A账户减少500,B账户增加500,这两个操作是同时成功或者失败。

二、事物的语法

   开启事务  begin  或  start  transaction   或   begin work

  事务回滚  rollback

  事务提交  commit

  还原点  savepoint  (不经常使用)

三、事务应该具备的4个属性:原子性、一致性、隔离性、持久性。通常称为ACID

  原子性:一个事务为一个不可分割的最小单位,里面的所有操作都是同时的。例如:转账必须同时成功。

  一致性:事务必须从一个一致性的状态变到另外一个一致性的状态。例如:转账前后AB的总额是不变的。

  隔离性:一个事务不能被其他的事务所干扰。各自操作各自的事务。

  持久性:一个事务被提交,就会永久的保存到数据库当中,对数据库的改变是永久的。

四、事务并发造成的问题

  脏读:A事务读取B事务更新的数据,然后B回滚,A读取的数据就是脏数据。

  不可重复读:A事务多次读取同一数据,事务在此过程中对数据进行了更新并提交,导致A事务多次多去数据时,结果不一样。

  幻读:事务A对表进行数据的修改,事务B提交了一条数据,导致有一个数据没有修改过来。

  不可重复读侧重于修改,幻读侧重于新增或删除。

  解决不可重复读锁住选中的行(行锁),解决幻读进行锁表(表锁)。

五、事务的隔离级别:

  未提交读(read uncommitted)会产生脏读。

  已提交读(read committed)不会产生脏读的数据,会产生不可重复读。

  可重复读(repeatable read)不会产生脏读的数据、不可重复读。产生幻读

  可串行化(serializable)不会产生脏读的数据、不可重复读、幻读

  

  -- 查询事务的隔离级别
  SHOW VARIABLES LIKE 'tx_isolation';
  -- 设置事务的隔离级别为 未提交读
  SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

  1:未提交读:开启A事务,执行更新,但是没有提交。在B事务内查询数据,就会出现脏读。

 

   

 2:已提交读:开始A事务,执行更新,没有提交。在B事务查询数据,不会出现脏读。但是A事务提交的时候,B事务再去查询就会更新数据,导致了不可重复读。

  

 3:可重复读 :开启A事务,增加一条数据,没有提交,在B事务也增加一条数据,会出现等待,直到A事务提交的时候才能提交。B事务在去查询就会出现两条数据。就会出现幻读。(可重复读会出现读锁)

  

  4:可串行化:开启A事务,增加一条数据,没有提交。B事务查询会等待,知道等到A事务提交,新增数据也是会等待。不会出现幻读,可重复读,脏读。(串行化会锁住整张表)

  

六、总结

  mysql的隔离级别为可重复读,如果有索引的时候,以索引为条件更新数据,会存在间隙锁、行锁、页锁等问题,锁住一些行。

  如果没有索引,更新数据会锁住整张表。没有索引的时候,就会使行锁升级为表锁。

  1:更新索引的数据时,会出现行锁。   更新没有索引的数据时,不会等待。

        

  2:没有索引的时候for update,会锁住整张表,会自动升级为表锁。更新都会等待。

      

  

  隔离级别越高,越能保证数据一致性,对并发性能影响也越大,对多数程序,可以优先把数据库的隔离级别设为read committed。 

  

原文地址:https://www.cnblogs.com/orange-time/p/10573790.html