MySQL的事务基础理论与锁的理解


1. 事务基础概论

事务比较常用于订单的生成,或者是支付,像这样一些涉及到支付,金额的场景都可以使用事务去避免一些异常而导致用户数据异常。
在代码中通常会使用try{}catch{}捕获异常的语句来配合事务使用。如果捕获到异常可以直接回滚整个事务,否则正常提交。即保证数据的一致性,原子性:要么都做,要么不做

事务的特性:

1. 事务要求 ACID 的特性,即:原子性、、一致性、、隔离性、、持久性。
2. 原子性:要么执行成功,要么执行失败。
3. 一致性:将数据库从一种一致性状态转换为下一种一致性状态。
4. 隔离性:一个事务的影响在该事务提交前对其他事务都不可见,它通过锁机制来实现。 
5. 持久性:保存在磁盘,数据会存储在重做日志中,当mysql出现异常而数据没能写入磁盘,但是事务已经提交,在下一次mysql服务重启时会自动执行重做日志写入数据,将数据写入文件当中。(事务一旦被提交,其结果就是永久性的,系统崩溃也不会影响)

在mysql中呢,事务也不是什么时候都可以使用的,他需要存储引擎的支持,
myisam 不支持事务
innodb  支持事务
BDB  支持事务,但是已经淘汰

 

查询事务是否自动提交

全局查询  show global variables like "autocommit"

局部查询  show session variables like "autocommit"

1就是设置为自动提交事务  set autocommit =1; 0就是关闭自动提交

 

事务基础操作

1. 在 MySQL 命令行的默认设置下,事务是自动提交的,即执行了SQL 语句之后会马上执行 commit 操作,我们可以设置 set autocommit=0 来禁用当前回话 的自动提交。
2. 还可以用 begin 、start transaction 来显式的开始一个事务。 
3. commit 在默认设置下是等价于 commit work 的,表示提交事务。 
4. rollback 在默认设置下等价于 rollback work,表示事务回滚。 
5. savepoint xxx 表示定义一个保存点,在一个事务中可以有多个保存点。 
6. release savepoint xxx 表示删除一个保存点,当没有该保存点的时候执行该语句,会抛出一个异常。 
7. rollback to [savepoint] xxx 表示回滚到某个保存点。

提出问题:事务的原子性与持久性是如何实现的?

通过重做日志和回滚日志来实现

2. 事务重做日志与回滚日志

重做日志:redo log=》ib_logfile0=》重新执行
回滚日志:undo_log=》ibdata =》回滚数据

注意:在mysql事务中一般都是“日志先行”,日志的优先权会大于实际数据操作,所有会执行的SQL都会先写日志,在写入数据

重做日志存储:
事务id,对应的sql语句

执行时间:
在mysql中事务执行commit提交了之后,但是服务器挂了,数据还没有写入磁盘,在mysql重启服务之后会重新执行这个重做日志写入数据。

回滚日志存储:
事务id,操作的数据元素,操作前数据,操作后数据

执行时间:
1. 手动执行回滚命令时会执行
2. 如果程序在事务执行之后,提交命令执行之前出现了异常,在下次mysql服务重启的时候会执行

事务日志文件操作:

-- 查看事务日志 :
show engine innodb status\G;
-- 查看日志文件设置状态
show variables like 'innodb_%';

2. 锁基础

2.1 概念

1. 在开发多用户、数据库驱动的应用时,相当大的一个难点就是解决并发性的问题,目前比较常用的解决方案就是锁机制。
2. 锁机制也是数据库系统区别于文件系统的一个关键特性。 
3. InnoDB 存储引擎和 MyISAM 存储引擎使用的是完全不同的策略,我们必须分开来讲。

2.2 锁类型

表级锁:锁住一张表的数据,开销小,加锁快,不会出现死锁的情况,锁定粒度大,发生锁冲突的概率更高,并发度最低。
存储引擎:myisam

页级锁:锁住一张表中某一页的数据,折中,一页数据的大小大概是16kb
存储引擎:BDB

行级锁:锁住的是一条记录,开销大,加锁慢,发生锁冲突的概率较低,并发度很高
存储引擎:innodb

行锁:
(1)共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。 
(2)排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务获得相同数据集的共享读锁和排他写锁。

(1)共享锁(S):select * from t1 where ... lock in share mode; 
(2)排他锁(X):select * from t1 where ... for update;

2.3 锁对于语句的加锁

结论:
共享锁:能读不能写,可以与共享锁一起使用,但是不能与排它锁一起使用
排它锁:能读不能写,也不能与其他锁一直使用

写的操作MySQL默认会加排它锁,add,update,delete

排它锁与共享锁使用场景:

在商城这种项目中,订单的生成以及商品的购买支付这样的场景,在支付的时候可以给操作的数据加把排它锁,去延迟消息的发送,防止有其他事务对于当前需要修改的用户数据做操作,而导致用户数据出现问题。
所以我们常在支付时会出现延迟的情况,支付完成后,要时间稍稍晚一些才能收到支付的信息。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值