事务和锁

事务

事务的基本概念

事务是作为单个逻辑单元所执行的一系列操作,如:新建一个数据库或表格,对表数据的插入、更新、删除,执行一个存储过程或函数等,都是一个事务。

事务控制

事务的控制有两种方法:

  1. 隐式事务
    隐式事务是不用管理员手动写的,是指单独的insert、update、delete默认是隐式事务,由系统自动提交。
  2. 显式事务
    显式事务就不是由系统自动提交的,是需要用户手动提交的。

关闭隐式事务自动提交

  • 查看自动提交变量的状态

    show variables like 'autocommit';
    #隐式事务自动提交是由一个变量来控制的。
    #它默认是打开的。
    
  • 通过设置自动提交变量的值为off或者0来关闭自动提交。

    #关闭自动提交
    set autocommit = off; #0#打开自动提交
    set autocommit = on; #1
    

回滚

没有设置提交的数据并没有从数据表中真实删除,就是因为数据没有自动提交,数据只是从查询结果集中删除了,此时我们打开另外一个命令列界面就可以查询出没提交之前的数据。
所以没有自动提交的数据是可以回滚(撤销)的。
回滚关键字:rollback

提交

确认事务,将没有自动提交的事务确认提交,也就是手动提交。
提交事务关键字:commit
确认提交后回滚就没有用了

显式事务

  • 开启显示事务
start transaction 
#在后面的语句里,暂停自动提交
  • 事务的显示控制

    set autocommit = 1; # 确认开启自动提交
    start transaction; # 开始显式事务
    delete from orders where id = 2; # 删除数据
    # 是否删除?rollback; # 回滚(不删除)
    commit; # 提交(确认删除)
    # 显示控制就相当于删除文件时会提示“是否确认删除”,需要手动提交。
    

事务的隔离

在数据库的使用过程中,无法避免的会有多个用户同时使用一个数据表的情况,所以就有了事务并发控制的概念,也就是每个用户的事务要隔离开来。

  • 查看当前隔离级别
    隔离级别有两种:
  1. 会话级别的隔离(当前连接有效):

    select @@session.tx_isolation;
    

    它是由一个会话变量tx_isolation保存的,MySQL默认为’REPEATABLE-READ’,可重读。

  2. 全局级别的隔离(当前服务有效):

    select @@global.tx_isolation;
    

    它是由一个全局变量tx_isolation保存的,MySQL默认为’repeatable-read’,可重读。

设置当前隔离级别

  • 会话级、全局级:
    #设置当前会话隔离级别为读未提交。
    set [global] session transaction isolation level read uncommitted;# 设置当前会话隔离级别为读提交。
    set [global] session transaction isolation level read committed;# 设置当前会话隔离级别为可重读(默认的)。
    set [global] session transaction isolation level repeatable read;# 设置当前会话隔离级别为串行化读。
    set [global] session transaction isolation level serializable;
    

测试隔离

这里以会话级别的隔离为例子。
首先打开两个cmd命令界面,进入Mysql,打开数据库。

#测试读未提交(read uncommitted)
#例如:首先设置两个会话的隔离级别都为读未提交
set session transaction isolation level read uncommitted;
#在第一个连接中开启显式事务,修改表中的数据
start transaction; # 开始显式事务
update test set age = 20 where id = 1; # 修改表中数据
#然后在另一个连接中查询相应的记录 # 查看读未提交的数据
select * from test where id = 1; # 这里就产生了脏读
#回到第一个连接中回滚此事务
rollback; # 回滚事务
#最后在另一个连接中查询相应的记录
select * from test where id = 1; # 查看回滚后的数据#测试可重读(repeatable read)
#例如:首先设置两个会话的隔离级别都为可重读
set session transaction isolation level repeatable read;
#在第一个连接中开启显式事务,查找表中的数据
start transaction; # 开始显式事务
select * from test where id = 1; # 查询出来的是原数据
#然后在另一个连接中修改相应的记录 # 修改数据
update test set age = 24 where id = 1; # 修改表中数据
#回到第一个连接查询记录
select * from test where id = 1; # 查询出来的是原数据
#最后提交事件:commit; 并再查询一遍记录
select * from test where id = 1; # 现在查询的就是新数据##测试串行化读(serializable)
#例如:首先设置两个会话的隔离级别为串行化读
set session transaction isolation level serializable;
##查看当前隔离级别:select @@session.tx_isolation;
##在第一个连接中开启显式事务,修改表中的数据
start transaction; # 开始显式事务
update test set age = 20 where id = 1; # 修改表中数据
#然后在另一个连接中开启显示事务,查询相应的记录 
select * from test where id = 1; # 查询没有反映
#回到第一个连接中提交事务:commit;
# 提交事务后另一个连接中才能查询出结果

锁的基本概念

锁是用于解决资源的共享使用的一种机制
只有在用户写时才需要加锁,用于保证数据的一致性。

锁的类型

MySQL中不同的存储引擎所使用的锁是不同的。

  1. 表级锁
    一个用户在访问一个表时,对整张表进行加锁,另外一个用户就访问不了这个表了。多个用户不能同时使用一张表。
    MyISAM和MEMORY存储引擎采用表级锁。
  2. 页面锁
    将表分成许多页,只对某一页加锁。页面锁可以精确到表的一部分,只锁表里的一部分数据。
    BDB存储引擎采用页面锁。

而innodb存储引擎采用表级锁和行级锁,默认是行级锁。

读锁和写锁

  • read读锁(共享锁)
    事务N在A对象上加了共享锁S,其他事务就不可修改表,但可以查询A,并且也可以加共享锁。
  • write写锁(排他锁)
    事务N在A对象上加了排他锁X,其他事务不可读不可写,也不可以加锁。

用户读数据时自动加read锁,修改数据自动加write锁。

  • 加锁

    Lock tables 表名 锁类型; # 锁类型:read/write
    
  • 解锁

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值