MySQL事物(重要)

x33g5p2x  于2022-05-22 转载在 Mysql  
字(2.4k)|赞(0)|评价(0)|浏览(196)

什么是事物

  • 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这组数据库命令要么都执行,要么都不执行。
  • 事务是一个不可分割的工.作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。
  • 事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等。
  • 事务通过事务的整体性以保证数据的一致性。
  • 事务能够提高在向表中更新和插入信息期间的可靠性。
  • 所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

转账是生活中常见的操作,比如从A账户转账100元到B账号。站在用户角度而言,这是一个逻辑上的单一操作,然而在数据库系统中,至少会分成两个步骤来完成:

  1. 将A账户的金额减少100元
  2. 将B账户的金额增加100元。

在这个过程中可能会出现以下问题:

  1. 转账操作的第一步执行成功,A账户上的钱减少了100元,但是第二步执行失败或者未执行便发生系统崩溃,导致B账户并没有相应增加100元。
  2. 转账操作刚完成就发生系统崩溃,系统重启恢复时丢失了崩溃前的转账记录。
  3. 非A用户的其他用户同时转账给B账户,由于同时对B账户进行操作,导致B账户金额出现异常。

为了便于解决这些问题,需要引入数据库事务的概念。

事务的四大特性(ACID)

原子性(Atomicity):事务的操作是不可分割的,“要么都不执行,要么全部执行”。

一致性(Consistency):事务执行完毕后会将数据库由一个一致性的状态变为另一个一致性的状态,数据库的一致性状态是指数据库中的数据满足完整性约束。

隔离性(Isolation):事务之间应该是彼此独立互不影响的,也就是一个事务的执行不会影响其他事务的执行。

持久性(Durability):事务在被提交(commit)后,它对数据库的改变是永久的(因为修改后的数据将会写入到硬盘中,硬盘会永久保留数据)

事务中可能会产生的问题

脏读

一个事务读取了另一个事务未提交的数据

不可重复读

同一事务两次查询读取同一数据,得到的结果不一致。(这是由于查询时系统中同时有其他事务进行操作提交而引起的)

幻读

幻读是不可重复读的一种特殊情景 ,A事物删除了2条数据, B事物增加了2条数据,然后A事物查询发现跟没有删除一样,或者一个事物两次范围查询的结果不一样:

事务的隔离级别


读为提交(read uncommitted):事务即使未提交,其他事务也能读

读已提交(read committed):事务只有提交后,其他事务才能读

可重复读(repeatable read):在同一个事务中,重复读取数据的结果也是相同的

可串行化(serializable):串行执行事务,一个事务提交(commit)或回滚(rollback)后,另一个事务才能开始。

注意:mysql的默认隔离级别:可重复读,mysql在执行事务(dml语句)的时候,会在表上加表锁,防止其他用户修改表中数据。(在执行dml语句时,select语句除外)

mysql事务相关语句

在Mysql中使用事物的前提条件必须在创建库的时候设置存储引擎为InnoDB 只有这个存储引擎支持事物
开启事务

-- 开启事务
start transaction;    -- 或者直接 BEGIN;

很多的博主都说要先设置set autocommit = 0关闭掉事务的自动提交属性才能使用 begin/commit或者begin/rollback的原子性操作,这是错误的。关于这一点,mysql官方文档做了详细的解释,下面是我引用的官方文档中的最重要的一句话
A session that has autocommit enabled can perform a multiple-statement transaction by starting it with an explicit START TRANSACTION or BEGIN statement and ending it with a COMMIT or ROLLBACK statement.

事务提交/回滚

rollback; -- 回滚
commit; -- 提交

简单的事物操作

start transaction; -- 开启事物

update qian set money = money + 100 where name = 'A';
select * from qian;
rollback;  -- 事物回滚
select * from qian;

查看当前会话的隔离级别

-- 查看当前会话的隔离级别
    select @@tx_isolation;

设置当前会话的隔离级别

-- 设置当前会话的隔离级别
    -- set session transaction isolation level 隔离级别;
    -- 举例:
    set session transaction isolation level read committed;

回滚点

很多时候,一个事务会包含多条语句,而出现问题需要回滚时,并不一定是要回滚到 begin 之前的状态,有可能是某条语句执行后的状态,这时需要用到savepoint定义回滚点,rollback 决定回滚到的位置

#开启一个事务
begin;

#更新表中A的money值+100
update qian set money = money + 100 where name = 'A';

select * from qian ;

#创建回滚点S1
SAVEPOINT S1;

#更新表B中的money值+100
update qian set money= money + 100 where name = 'B';

select * from qian;

#创建回滚段S2
SAVEPOINT S2;

#再次插入一条数据记录
insert into qian values(3,'C',1000);

select * from qian ;
 
ROLLBACK TO S1;

#回滚到回滚点S1
select * from qian;

点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复如有侵权,请私信联系我感谢,配合,希望我的努力对你有帮助^_^

相关文章

微信公众号

最新文章

更多