一、事务
事务处理可以用来维护数据库完整性,保证成批的SQL语句要么全部执行,要么全部不执行。
事务的特性:
ACID
原子性:一个事务不可再分割,要么都执行要么都不执行
一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态
隔离性:一个事务的执行不受其他事务的干扰
持久性:一个事务一旦提交,则会永久的改变数据库的数据.
1.1 例子
张三账户转账100元至李四账户
操作:1.张三账户减去100元
2.李四账户增加100元
如果我们更新完张三的账户后,准备更新李四账户的时候出现了错误。这样子就导致了数据不一致,为了保证数据的一致性,这个时候我们就可以使用事务。
mysql中用begin roollback commit 来实现事务
1.BEGIN 开始一个事务
2 ROLLBACK 事务回滚
3.COMMIT 事务确认
在 begin 与 commit 之间的任何执行语句 都不会实际修改数据库数据,等到commit执行以后 才会修改数据库数据。
use bank;
SELECT * from `user`;
BEGIN;
UPDATE `user` SET BALANCE =BALANCE-100 WHERE ID =1; #张三减去100元
UPDATE `user` SET BALANCE =BALANCE+100 WHERE ID =2; #李四增加100元
COMMIT;
如果在begin开启后 执行语句时发生了错误 可以手动执行 ROLLBACK;
操作,这样子数据就返回到了执行语句以前的状态。
事务的创建
1.2 隐式事务:事务没有明显的开启和结束的标记
比如insert、update、delete语句
delete from 表 where id =1;
1.3 显式事务:事务具有明显的开启和结束的标记
前提:必须先设置自动提交功能为禁用
set autocommit=0;
步骤1:开启事务
set autocommit=0;
start transaction;可选的
步骤2:编写事务中的sql语句(select insert update delete)
语句1;
语句2; …步骤3:结束事务
commit;提交事务
rollback;回滚事务savepoint 节点名;设置保存点
1.4.演示事务对于delete和truncate的处理的区别
#最后没删除
SET autocommit=0;
START TRANSACTION;
DELETE FROM account;
ROLLBACK;
#删除了
SET autocommit=0;
START TRANSACTION;
truncate table account;
ROLLBACK;
1.5 同时运行事务 产生问题
1.脏读:
对于两个事务T1,T2,T1读取了已经被T2**更新但还没有提交**的字段之后,若T2回滚,T1读取的内容就是临时且无效的
-
不可重复读
对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1再次读取同一个字段,值就不同了。
-
幻读
对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行,如果T1再次读取同一个表,就会多出几行。
事务的隔离级别:
脏读 不可重复读 幻读
read uncommitted:√ √ √
read committed: × √ √ 避免 脏读
repeatable read: × × √
serializable × × ×
mysql中默认 第三个隔离级别 repeatable read
mysql中默认 第三个隔离级别 repeatable read
1.6.演示savepoint 的使用 28没删 回滚到25删除后
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点
二、锁 表级索
2.1 添加读锁
可以并发读,但是不能并发写,读锁期间,没释放锁之前不能进行写操作。
LOCK TABLE USER READ; #上读锁
UNLOCK TABLES; #解锁
设有dos命令窗口1 执行了LOCK TABLE USER READ;
那么如果在dos命令窗口1里执行修改语句会出现报错
Table ‘user’ was locked with a READ lock and can’t be updated
这时候如果在dos命令窗口2里执行修改操作,那么dos命令窗口2会进行等待状态,只有dos命令窗口1 执行了UNLOCK TABLES
,dos命令窗口2才会执行修改语句完成。
2.2 添加写锁
只有锁表的用户才可以进行读写操作,其他用户均不行。
lock table user write;#添加写锁
unlock tables;#释放写锁
设有dos命令窗口1执行lock table user write;
,那么dos命令窗口2里进行的读写操作将会被搁置,只有等到dos命令窗口1执行unlock tables;
dos命令窗口2才能执行操作。