MySQL-事务
1.事务的基本介绍
1.概念
2.操作
1.开启事务,添加在在执行操作语句之前,添加开启事务:start transaction;
2.回滚事务,添加在执行操作语句后,如果发现操作出现错误,则添加回滚事务的操作,操作会回滚到start transaction之前:rollback;
3.提交事务,添加在执行操作语句后,事务操作成功,但是数据库却没有更新(打开了两个sqlyog连接的都是同一个数据库,在第一个sqlyog中操作数据让张三给李四转500块钱,第一个sqlyog操作成功,但是第二个显示的还是操作之前的数据):commit;
3.举例
模拟张三给李四转 500 元钱,一个转账的业务操作最少要执行下面的 2 条语句: 张三账号-500 李四账号+500
-- 创建数据表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE );
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('张三', 1000), ('李四', 1000);
-- 模拟张三给李四转 500 元钱,一个转账的业务操作最少要执行下面的 2 条语句: 张三账号-500 李四账号+500
-- 张三账号-500
update account set balance = balance - 500 where name='张三';
-- 李四账号+500
update account set balance = balance + 500 where name='李四';
假设当张三账号上-500 元,服务器崩溃了。李四的账号并没有+500 元,数据就出现问题了。我们需要保证其中 一条 SQL 语句出现问题,整个转账就算失败。只有两条 SQL 都成功了转账才算成功。这个时候就需要用到事务
start transaction;
-- 张三账号-500
update account set balance = balance - 500 where name='张三';
-- 李四账号+500
update account set balance = balance + 500 where name='李四';
rollback;
commit;
4.mysql数据库默认自动提交
事务提交的两种方式:
1.自动提交:不需要commit,所有的DML操作都会自动提交,保存,即使是打开多个图形化界面窗口或者是关掉图形化界面窗口再打开都会自动更新操作后的数据
mysql全部默认自动提交的(除非你加了事务,那事务以外的操作仍然是自动提交,事务有关的操作是手动提交)
一条DML(增删改)语句会自动提交一次事务(但凡没有在start transaction中的操作都会自动提交)
2.手动提交:需要commit,如果没有commit,则所有的DML操作都只存留在当前图形化界面上修改了,并没有对数据库进行操作,多个图形化界面窗口或者是关掉图形化界面窗口再打开都会自动更新操作后的数据
Oracle数据库全部默认是手动提交的(无论是否加了事务,操作完数据库都要commit提交)
需要先开启事务,再提交(事务内的操作都需要手动提交)
修改事务的默认提交方式:
查看事务的默认提交方式:SELECT @@autocommit; --结果为1则是自动提交,结果为0是手动提交
修改默认的提交方式(如果修改成手动提交,则无论是否是在事务内的操作,全部都需要commit提交,和Oracle数据库一样):set @@autocommit=0;
2.事务的四大特征
1.原子性:事务是不可分割的最小操作单位,要么同时成功,要么同时失败(一个事务里可能有多个操作,如果某一个操作失败了,其他操作没有失败,则也全部都认为失败,事务就会回滚)
2.持久性:当事务提交或回滚后,数据库会持久化的保存数据(一旦提交(无论是自动提交还是手动提交)以后,修改了数据库,即使窗口关闭,也会保持修改后的数据)
3.隔离性:多个事务之间,相互独立(一个事务不会影响其他事务(但是这是很难的,需要事务的隔离级别来帮助))
4.一致性:事务操作前后,数据总量不变(比如转账,无论是回滚,还是提交,转账人的钱和收账人的钱加起来是相同且不变的)
3.事务的隔离级别
概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就会解决这些问题
存在问题:
1.脏读:一个事务,读取到另一个事务没有提交的数据
2.不可重复读(虚读):在同一个事务中,两次读取到的数据不同
3.幻读:一个事务操作(DML)数据表中的所有记录,另一个事务添加一条数据,则第一个事务查询不到自己的修改
隔离级别
1.read uncommitted:读未提交(读取未提交的数据)
产生的问题:脏读、不可重复读(虚读)、幻读
2.read committed:读已提交(读取已提交的数据)
产生的问题:不可重复读(虚读)、幻读
3.repeatable read:可重复读(MySQL默认)
产生的问题:幻读
4.serializable:串行化
可以解决所有问题
注意:隔离级别从上到下安全性越来越高,但是效率越来越低
查询隔离级别: select @@tx_isolation;
设置隔离级别 set global transaction isolation level 级别字符串;