一、事务概述
Transaction Control Language 事务控制语言事务:
一个或一组sql语句 组成一个执行单元,这个执行单元要么全部执行,要么全部不执行一旦执行失败或产生错误,整个单元将会回滚 ,所有受到影响的数据将返回到事物开始以前的状态 MySQL存储引擎: SHOW ENGINES;
查看存储引擎
innodb支持事务 myisam、memory等不支持事务 事务的特性:(ACID)
Atomicity原子性:一个事务不可再分割,要么都执行要么都不执行 Consistency一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态 Isolation隔离性:一个事务的执行不受其他事务的干扰 Durability持久性:一个事务一旦提交,则会永久的改变数据库的数据
二、事物的创建
事务的创建:
隐式事务:事务没有明显的开启和结束的标记
比如insert、update、delete语句 SHOW VARIABLES LIKE 'autocommit';
autocommit自动开启 delete from 表 where id =1;
这就是一个事务 显式事务:事务具有明显的开启和结束的标记
前提:必须先设置自动提交功能为禁用 set autocommit=0;
针对当前事务有效
语法:
步骤1 :开启事务
set autocommit= 0 ;
start transaction ;
步骤2 :编写事务中的sql 语句( select insert update delete ) 即增删改查
语句1 ;
语句2 ;
savepoint 节点名; 设置保存点
. . .
步骤3 :结束事务
commit ; 提交事务
rollback ; 回滚事务
rollback to 节点名; 回滚到指定地方
DROP TABLE IF EXISTS account;
CREATE TABLE account(
username VARCHAR ( 10 ) ,
balance INT
) ;
INSERT INTO account
VALUES ( '张无忌' , 1000 ) ,
( '赵敏' , 1000 ) ;
SET autocommit= 0 ;
START TRANSACTION ;
UPDATE account SET balance = 500 WHERE username= '张无忌' ;
UPDATE account SET balance = 1500 WHERE username= '赵敏' ;
ROLLBACK ;
SELECT * FROM account;
SET autocommit= 0 ;
START TRANSACTION ;
DELETE FROM account;
ROLLBACK ;
SET autocommit= 0 ;
START TRANSACTION ;
TRUNCATE TABLE account;
ROLLBACK ;
SET autocommit= 0 ;
START TRANSACTION ;
DELETE FROM account WHERE username= '张无忌' ;
SAVEPOINT a;
DELETE FROM account WHERE username= '赵敏' ;
ROLLBACK TO a;
三、事物的隔离
3.1 不隔离的问题
对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
脏读 :一个事务读取了其他事务还没有提交的数据,读到的是其他事务“更新”的数据
例如:对于两个事务T1 T2, T1 读取了已经被T2 更新但还没有被提交的字段. 之后, 若T2 回滚, T1读取的内容就是临时且无效的. 不可重复读 :一个事务多次读取,结果不一样
例如:对于两个事务T1 T2, T1 读取了一个字段, 然后T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了. 幻读 :一个事务读取了其他事务提交的数据,读到其他事务后“插入”的数据
例如:对于两个事务T1 T2, T1 从一个表中读取了一个字段, 然后T2 在该表中插入了一些新的行. 之后, 如果T1 再次读取同一个表, 就会多出几行.
3.2 事务的隔离级别
数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题.
事务的隔离级别:一个事务与其他事务隔离的程度称为隔离级别.
脏读 不可重复读 幻读
【read uncommitted 】√ √ √
读未提交数据:允许事务读取未被其他事务提交的变更
【read committed 】 × √ √
读已提交数据:只允许事务读取已被其他事务提交的变更
【repeatable read 】 × × √
可重复读: 确保事务可以多次从一个字段中读取相同的值,
在该事务持续期间,禁止其他事务对这个字段进行更新
【serializable 】 × × ×
串行化: 确保事务可以从一个表中读取相同的行
在该事务持续期间,禁止其他事务对该表执行插入、更新、删除
所有问题都能解决但性能低下
mysql中默认 第三个隔离级别 repeatable read
oracle中默认第二个隔离级别 read committed
在cmd中进行如下操作:
查看隔离级别
select @@tx_isolation ;
设置隔离级别
set session | global transaction isolation level 隔离级别;
( 当前mySQL连接| 全局的隔离级别)