1、 介绍
什么是事务?
事务是一个原子操作。是一个最小执行单元。可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败。(
一组操作同时成功,或同时失败
)
场景:
银行
转账
操作,A账号要给B账户转钱. A原有1000块,B原有1000块.A转账给B 100元A的钱要减少,B的钱要增多
update A set money = money - 100 where id = a -- 服务器出现异常,导致后面的sql没有执行 update B set money = money + 100 where id = b
2、 mysql中事务
目前使用的mysql支持事务操作
mysql中的事务是
每个sql语句都是单独事务
,且自动提交事务的
通过命令查询当前事务的提交方式 SHOW VARIABLES like 'autocommit'
通过命令设置自动提交关闭 set autocommit = off / 或者= 0 关
set autocommit = on / 或者= 1 开
事务的操作
开启事务 start transaction 或者 begin
提交事务 commit
回滚事务 rollback
3、 演示事务
准备数据
CREATE TABLE `account` (
`id` int(50) NOT NULL,
`name` varchar(50) NOT NULL,
`money` int(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO account VALUES(1,'张三',1000);
INSERT INTO account VALUES(2,'李四',1000);
-- =============================================
-- 开启事务
start transaction;
-- 开始转账
update account set money = money - 100 where id = 1
-- 出大事了,后面执行不了
update account set money = money + 100 where id = 2
-- 如果一切正常,提交事务
commit;
-- 服务器出现异常,要回滚
rollback;
-- 查询当前事务提交方式
SHOW VARIABLES like 'autocommit';
-- 手动控制事务,自动提交关闭
set autocommit = off;
-- ============= java 伪代码 ==================
try{
conn.setAutocommit(false); -- 自动提交,开启手动事务
conn.execute("update ....")
System.out.print(1/0)
conn.execute("update ....")
conn.commit(); -- 提交
}catch(Exception e) { -- 如果有异常
conn.rollback(); -- 回滚
}
-- 后面学框架,只需要配置一下就ok,一个注解搞定
4、 事务特性
事务的特性(ACID)
原子性(Atomicity):指事务的整个操作是一个整体,要么都成功,要么都失败
一致性(Consistency):事务必须使数据库从一个一致性状态变换到另外一个一致性状态。转账前和转账后的总金额不变。
隔离性(Isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一 个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability):指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。回滚不了的
5、 事务的隔离机制
数据库有不同的隔离机制/隔离级别
读未提交-READ UNCOMMITTED: 赃读、不可重复读、虚读都有可能发生。
读已提交-READ COMMITTED: 避免赃读。不可重复读、虚读都有可能发生。
(oracle 默认的)
可重复读-REPEATABLE READ:避免赃读、不可重复读。虚读有可能发生。
(mysql 默认)
,行锁串行化-SERIALIZABLE: 避免赃读、不可重复读、虚读。
串行化,其实是表锁
查看当前数据库的隔离级别: SELECT @@TX_ISOLATION;
更改当前的事务隔离级别:
SET [glogal | session] TRANSACTION ISOLATION LEVEL 四个级别之一。
赃读:指一个事务读取了另一个事务未提交的数据。
对于两个事物 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。一个事务读取到了另一个事务提交后的数据。(update)
对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。 (insert)
对于两个事物 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中 插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行
总结一些常用的问题
1 什么是事务 2 mysql事务怎么操作(开启,提交,回滚) 3 事务什么特点(ACID) 4 什么是事务隔离(能解释) 5 有哪些级别,简单解释 6 mysql默认什么级别