数据库事务和锁

这里用MySQl为例

事务
作为单个逻辑工作单元执行的一系列操作。
事务特性 ACID
A atomicity  原子性
事务是不可分割的原子单元,要么全部完成,要么全部不完成,不可能停在中间。操作成功 整个事务提交 commit  操作失败 事务回滚 rollback
A给B转账
A扣款  B到账
C consistency 一致性
A给B转账
A转了1000  B只到了500 
I isolation 隔离性
多个事务并发访问,事务之间是隔离的
D durabiliy 持久性
事务一旦提交,持久化保存在数据库
断电,重启都不会改变数据

事务控制
隐式事务
单独的insert,update,delete 默认是隐式事务,系统自动提交
set autocommit=0;
insert into orders values(7,200,now(),'danny');
commit;
insert into orders values(8,400,now(),'danny');
rollback;
delete from orders where id=7;
显式事务
用户自定义事务,显式提交
start transaction
insert into orders values(7,200,now(),'danny');
commit;

事务隔离级别
read-uncommitted(读未提交)
最低隔离级别  一个事务可以读到另一个事务未提交的结果,导致 脏读
read-committed(读提交)
只有在事务提交之后,其他事务才能看见,可以避免脏读,会导致 不可重复读
repeatable-read(可重读)
一个事务中,对同一份数据读到的结果总是相同的,可以避免不可重复读 会导致 幻读
serializable(串行化)
事务串行化执行,隔离级别最高,牺牲系统并发性,可以解决并发事务所有问题

脏读:  一个事务可以读取另一个尚未提交的事务数据
不可重复读: 事务A多次读取同一数据, 事务B在事务A多次读取的过程中, 对数据作了更改并提交, 导致事务A多次读取同一数据时, 结果不一致, 可能被更新, 可能被删除。
幻读: 在同一事务中, 同一查询多次进行时候, 由于其他插入操作(insert) 的事务提交,导致每次返回不同的结果集。
不可重复读重点在于 update 和 delete , 幻读的重点在于 insert 。

my.ini
#read-uncommitted
#read-committed
#repeatable-read
#serializable
[mysqld]
transaction-isolation =read-committed

--read uncommited
--read committed
--repeatable read
--serializable
set [global | session] transaction isolation level read committed
--查看会话级隔离级别
select @@session.tx_isolation;
select @@tx_isolation;
--查看全局级隔离级别
select @@global.tx_isolation;

事务隔离级别验证
准备:
create table t1(
    id int primary key auto_increment,
    name varchar(20),
    age int
)engine=innodb default charset=utf8;
insert into t1 values(null,'夏七',38),(null,'danny',40);
验证read uncommitted

set session transaction isolation level read uncommitted;

start transaction;
update t1 set age=18 where id=1;

select age from t1 where id=1;

验证read committed
验证repeatable read
验证serializable


计算机协调多个进程或者线程并发访问某一资源的机制
数据库上操作可以归纳读和写
同时读不会有冲突,同时写或者同时读和写才可能产生冲突

不同的存储引擎支持不同的锁机制
MyISAM和MEMORY存储引擎采用表级锁
BDB存储引擎采用页面锁,也支持表锁
InnoDB存储引擎默认采用的是行级锁,也支持表锁

表级锁 开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突概率最高,并发度低
行级锁 开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突概率最低,并发度最高
页面锁 开销和加锁介于表级锁和行级锁之间,会出现死锁,锁定粒度介于表级锁和行级锁之间,并发度一般

死锁  相互等待对方持有的锁
锁定粒度:锁定对象的大小   表 页  行
锁冲突  等待别人释放锁

MyISAM锁
在用户读数据自动加read锁,改数据自动加write锁
lock tables         unlock tables
create table t2(
    id int primary key auto_increment,
    name varchar(20),
    age int
)engine=myisam default charset=utf8;
insert into t2 values(null,'夏七',38),(null,'danny',40);
read是共享锁   write是排他锁 独占锁
会话1给表加读锁
会话1只能读加锁的表数据   会话2可以读表
会话1不能改数据           会话2能改数据要等待

会话1给表加写锁
会话1读加锁的表数据       会话2可以读数据要等待
会话1能改数据                会话2可以改数据要等待

锁并发操作
MyISAM存储引擎读锁和写锁互斥,读写是串行的,但是在一定条件下可以实现并发
MyISAM存储引擎提供了一个系统变量concurrent_insert,控制并发插入0,1,2
0 不允许并发
1 如果MyISAM的表没有空洞,允许一个进程读表的同时,另一个进程从表尾插入记录,是MyISAM默认设置
2 不管MyISAM的表有没有空洞,都允许在表尾插入记录
my.ini  
concurrent_insert=2 重启MySQL服务允许并发

使用 需要一次锁定用到的所有表,同一表在SQL出现多少次别名,也要对别名锁定多少次
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淮城一只猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值