·事务简介
事务是一组操作的集合,他是不可分割的一个工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么全部成功,要么全部失败。
每条sql操作都是一个事务,mysql中sql语句自动提交。
举例:
如果是银行转账行为,需要三步进行操作:查询A余额,A余额减1000,B余额加1000。如果第三步出现异常,那么需要进行事务回滚,将A余额减少的1000恢复,不然就会有1000凭空消失。
所以,事务要求全部成功,或者全部失败。
注意:
由于mysql中都是自动提交,所以需要手动开启事务,手动提交事务和手动回滚事务。
·事务操作
例子:
银行转账:A给B转1000;
正常情况:
select * from account where name = 'A';
update account set money = money - 1000 where name = 'A';
update account set money = money + 1000 where name = 'B';
异常情况:
select * from account where name = 'A';
update account set money = money - 1000 where name = 'A';
23432123ecvdsw
update account set money = money + 1000 where name = 'B';
这里A会减少1000,B余额不会变。
方式一:
修改事务提交方式,自动改为手动,然后出错手动回滚,没错手动commit。
查看/设置事务提交方式
SELECT @@autocommit; -- 查看事务的提交方式,1是自动提交,0是手动提交
SET @@autocommit = 0; -- 把事务设置为手动提交
提交事务:
COMMIT;
回滚事务:
ROLLBACK;
展示:
SELECT @@autocommit;
SET @@autocommit = 0;
select * from account where name = 'A';
update account set money = money - 1000 where name = 'A';
23432123ecvdsw
update account set money = money + 1000 where name = 'B';
这里A会减少1000,B余额不会变。
commit; -- 提交,修改的是一张表的事务提交方式,每次执行操作后都要执行commit
rollback; -- 回滚,出错了执行这个手动回滚。
方式二:
开启事务:
START TRANSACTION 或 BEGIN;
提交事务:
commit;
回滚事务:
rollback;
展示:
start transaction;
select * from account where name = 'A';
update account set money = money - 1000 where name = 'A';
23432123ecvdsw
update account set money = money + 1000 where name = 'B';
这里A会减少1000,B余额不会变。
commit; -- 提交,修改的是一张表的事务提交方式,每次执行操作后都要执行commit
rollback; -- 回滚,出错了执行这个手动回滚。
·事务四大特性
原子性:事务具备原子性,说明事务是数据库中最小的工作单位,事务的原子性确保数据库操作过程中的所有步骤的全部成功或全部失败;
一致性:指事务对于数据进行修改操作,要求数据修改前和修改后的状态保持一致。例如:银行转账业务的事务无论是否成功,转账者和收款人的总额应该保持不变;
隔离性:是指一个事务的执行不能被其他事务干扰,一个事务的操作和使用的数据,对并发中的其他事务是隔离的
持久性:是指一个事务一旦被提交,他对数据库的改变是永久性的
·并发事务问题
可能引发的问题:
问题 |
描述 |
脏读 |
一个事务督导另一个事务还没提交的数据 |
不可重复读 |
一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。 |
幻读 |
一个事务按照条件查询数据时,没有对应的数据行,但在插入数据时,又发现这行数据已经存在,好像出现了幻影。 |
·事务隔离级别
事务隔离级别是数据库管理系统中的一个重要概念,用于定义事务在并发执行时的隔离程度。以下是四种常见的事务隔离级别及其特点:
- Read Uncommitted(读未提交):
-
- 允许读取到其他事务尚未提交的数据。
- 可能导致脏读(Dirty Read),即读取到其他事务未提交的数据,这些数据可能在未来被回滚,导致读取的数据无效。
- 可能出现不可重复读(Non-repeatable Read)和幻读(Phantom Read)的问题。
- Read Committed(读已提交):
-
- 只允许读取到已经提交的数据。
- 避免了脏读的问题,但可能出现不可重复读的问题,因为其他事务可能在两次读取之间修改了数据。
- 可能出现幻读的问题,因为其他事务可能在两次读取之间插入了新数据。
- Repeatable Read(可重复读)(mysql的默认隔离级别):
-
- 默认隔离级别,用于防止脏读问题。
- 使用锁机制来防止不可重复读和幻读的问题。
- 并发能力较差,可能导致较高的锁代价和系统性能开销。
- Serializable(可串行化):
-
- 最高隔离级别,实现串行化读取数据。
- 通过在读取的数据上加锁,防止数据冲突,从而避免脏读、不可重复读和幻读的问题。
- 但会导致大量超时和锁竞争问题,影响系统性能。
不同的事务隔离级别提供了不同程度的隔离,以满足不同应用场景对于一致性和性能的需求。在选择事务隔离级别时,需要在数据一致性和系统性能之间进行权衡。
查看和设置事务的隔离级别:
查看:
SELECT @@TRANSACTION_ISOLATION;
事务隔离级别:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL { READUNCOMMTTED | READ COMMITTED │ REPEATABLE READ | SERALZABLE}