MySQL 事务

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

简单点说:完成一件事所需要执行的所有操作,如果其中一个操作没成功则回到原点,全部成功则提交。


下面简单介绍下事务的特性:

  1. 原子性:一个事务就是一个完整的整体,要么成功,要么失败;
  2. 一致性:事务从一个状态集体变为另一个状态;
  3. 隔离性:事务之间不存在相互干扰,开始执行不被其他因素影响;
  4. 持久性:(永久性),提交后结果永久保存,其他操作或者故障不会对其执行结果产生影响。

针对上述特性举个例子:去超市买东西,需要两个环节,选东西,结账带走,这俩步骤缺一不可(原子性),直接拿走东西不付钱或者付钱不拿东西均未完成交易(原子性,一致性);选好东西去结账时,别人不能从自己手里将东西抢走(隔离性);结账完成交易成功,这时你结账给超市的钱丢了或者自己买的东西损坏都不会对之前的交易结果产生影响(持久性)。


下面就是事务的隔离级别了:(提前声明,以下内容均为并发场景,不存在并发则不会存在以下问题)

借用网上一张流传非常广泛的图

没了解过一看有点蒙,下面具体介绍。

先介绍几个名词:

  1. 脏            读:事务A 两步,执行第一步更新完成数据,B读取该数据,此时A第二步执行失败回滚,B读取数据就会与数据库中              数据不一致,读取内容不正确。
  2. 不可重复读:事务A 两步,均对同一条数据操作,在两次读取数据数据结果中间,存在事务B对同一条数据执行更新操作,导致事务A两步读取结果不一致。
  3. 幻            读:事务A两步, 第一步读取存在5条记录,此时B插入2条数据,A第二步读取发现存在7条,两条是之前不存在的,就和出现幻觉一样。

mysql针对以上三个问题提供事务隔离级别,也就是针对以上问题提供的解决办法:

  1. 读未提交,以上问题均未解决;
  2. 读已提交:解决脏读问题,其他俩问题依然存在;
  3. 可重复读:解决脏读、不可重复读问题;
  4. 可串行化:以上问题全部解决,性能差;

在实际场景中直接设置为串行化性能太差,无法满足实际生产需求,故隔离级别一般设为读已提交,不可重复读和幻读在业务中处理,这就是咱们接下来介绍的锁。


表锁、行锁:mysql常见的锁机制

  1. 表锁:MyISAM、MEMORY
  2. 行锁:InnoDB
  3. 还存在另外一种特殊的页面锁:BDB  -<这个存储引擎我工作中没用过

上面两种锁优劣势

表锁:加锁快,不存在死锁,锁定颗粒大,容易出现锁冲突,并发小;

行锁:加锁满,会出现死锁,锁定颗粒小,发生锁冲突概率低,并发高;

 

读锁(共享锁)、写锁(排它锁)

  1. 类似的还存在意向共享锁、意向排它锁,意向锁均mysql内部机制,是表锁,实际开发中不涉及
  2. 开发中会使用读锁,写锁,均行锁。

mysql自带的:

  1. InnoDB :执行写操作(update,insert,delete)前自动给涉及数据加写锁,select不加任和锁;InnoDB行锁是给索引项加锁来实现行锁的,这就意味着只有命中索引才会使用行锁,不然仍然是表锁;
  2. MyISAM:执行写操作添加涉及到的表加写锁,读操作前添加读锁(均表锁);

乐观锁、悲观锁

  1. 悲观锁:对一切事务操作保持保守态度,操作过程中相关数据均处于锁定状态。基本上是基于mysql本身锁机制实现,系统中及时实现也无法保证另外系统的干涉。
    1. mysql默认为autocommit模式,如果使用悲观锁,需修改为手动提交。
      1、登录mysql,查看autocommit状态。
      SHOW VARIABLES LIKE 'autocommit';
      on  :自动提交   1
      offf:手动提交   0
      
      2、mysql数据库怎么设置手动提交
      把autocommit改成off;
      set @@autocommit=0; #值设置为0或者 off 都生效
      
      3、mysql数据库怎么设置手动提交,启动数据库时自动设置autocommit=0。
      在mysql目录中找到这个文件my.ini
      在[mysqld]之后写上:autocommit=0
      启动数据库。
      

       

  2. 乐观锁:相对悲观锁,乐观锁默认操作不会冲突,只有 在提交是才去进行是否冲突检测,如果冲突才会返回信息,让用户决定如何处理(回滚)。一般乐观锁处理方式:
    1. 数据积累增加一版本(version) 或者标记(sign)。通过对version或者sign的前后操作一致性进行比较,从而确定是否更新。(比如:读取数据时一同获取version值并记录,执行更新操作对version+1,如果读取时获取版本与上次版本不一致则表示过期。)
    2. 记录最后一次更新时间,与上面类似,如果时间发生变更则数据冲突。
  3. 总结:乐观锁悲观锁各有利弊。如果读多写少则建议使用乐观锁,可以省去锁消耗的性能。但如果冲突产生很多,反而会不停地回滚,消耗更多的性能,这样子悲观锁就优势了。实践中高并发场景较多,此时乐观锁要优于悲观锁。悲观锁会使每个线程等待时间变长,影响性能,乐观锁则可以一定程度上提高并发。

 

所有的技术均需结合实际生产环境进行性价比评估,努力寻找最优解,并不存在绝对的最优。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 事务是指一组数据库操作,这些操作要么全部执行,要么全部不执行,其目的是保证在并发环境下,数据的一致性和完整性。MySQL 事务具有 ACID 性质,即原子性、一致性、隔离性和持久性。 MySQL 中使用事务需要使用 BEGIN、COMMIT 和 ROLLBACK 语句,其中 BEGIN 表示开启一个事务,COMMIT 表示提交事务,ROLLBACK 表示回滚事务事务的基本语法如下: ``` BEGIN; -- 执行一组数据库操作 COMMIT; -- 提交事务 -- 或者 ROLLBACK; -- 回滚事务 ``` 在 MySQL 中,事务隔离级别分为四个等级,分别是 Read Uncommitted、Read Committed、Repeatable Read 和 Serializable。隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。 MySQL 事务的 ACID 性质有以下含义: 1. 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部失败回滚,不会只执行其中的一部分操作。 2. 一致性(Consistency):事务执行前后,数据库中的数据必须保持一致性状态,即满足数据库的约束条件和完整性规则。 3. 隔离性(Isolation):事务之间应该是相互隔离的,一个事务的执行不应该被其他事务干扰,保证事务之间的数据相互独立。 4. 持久性(Durability):事务提交后,对数据库的修改应该是永久性的,即使出现系统故障或电源故障,也不应该对数据产生影响。 总之,MySQL 事务是一组数据库操作,具有 ACID 性质,可以通过 BEGIN、COMMIT 和 ROLLBACK 语句来实现,隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值