事务就是用户定义的一系列执行SQL语句的操作, 这些操作要么完全地执行,要么完全地都不执行, 它是一个不可分割的工作执行单元。
在日常生活中,有时我们需要进行银行转账,这个银行转账操作背后就是需要执行多个SQL语句,假如这些SQL执行到一半突然停电了,那么就会导致这个功能只完成了一半,这种情况是不允许出现,要想解决这个问题就需要通过事务来完成。
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性.
数据库总是从一个一致性的状态转换到另一个一致性的状态。(在前面的例子中,一致性确保了,即使在转账过程中系统崩溃,支票账户中也不会损失200美元,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。)
通常来说,一个事务所做的修改操作在提交事务之前,对于其他事务来说是不可见的。(在前面的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外的一个账户汇总程序开始运行,则其看到支票帐户的余额并没有被减去200美元。)
一旦事务提交,则其所做的修改会永久保存到数据库。
说明:事务能够保证数据的完整性和一致性,让用户的操作更加安全。
原子性: 强调事务中的多个操作时一个整体
一致性: 强调数据库中不会保存不一致状态
隔离性: 强调数据库中事务之间相互不可见
持久性: 强调数据库能永久保存数据,一旦提交就不可撤销
MySQL数据库默认采用自动提交(autocommit)模式, 也就是说修改数据(insert、update、delete)的操 作会自动的触发事务,完成事务的提交或者回滚
开启事务使用 begin 或者 start transaction; 事务 81
回滚事务使用 rollback;
pymysql 里面的 conn.commit() 操作就是提交事务
pymysql 里面的 conn.rollback() 操作就是回滚事务
一个事务的执行不能被其他事务干扰,事务之间的相互影响分为几种,分别为脏读、不可重复读、幻读、丢失更新。
脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据,读到了不一定最终存在的数据,这就是脏读。
一个事务内两个相同的查询却返回了不同数据,这是由于查询时系统中其他事务修改的提交而引起的。
一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,操作前一个事务的用户 会发现表中还有没有修改的数据行,就好像发生了幻觉一样。
两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。
read_uncommitted (未提交度): 读取尚未提交的数据 :不解决脏读
read_committed(提交读):读取已经提交的数据 :可以解决脏读
repeatable_read:(可重复读):可以解决脏读 和 不可重复读 —mysql默认的
serializable:串行化:可以解决脏读、不可重复读和虚读—相当于锁表
mysql默认的事务处理级别是 repeatable read ,而Oracle和SQL Server是 read committed
事务隔离级别的作用范围分为两种:
全局级:对所有的会话有效
会话级:只对当前的会话有效
show global variables like '%isolation%';
select @@global.tx_isolation;
show session variables like '%isolation';
select @@session.tx_isolation;
select @@tx_isolation;
set global transaction isolation level serializable;
show global variables like '%isolation%';
set session transaction isolation level read committed;
BEGIN 或 START TRANSACTION:显式地开启一个事务。
COMMIT 或 COMMIT WORK:提交事务,并使已对数据库进行的所有修改变为永久性的。
ROLLBACK 或 ROLLBACK WORK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
SAVEPOINT S1:使用 SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT;“S1”代表回滚点名称。
ROLLBACK TO [SAVEPOINT] S1:把事务回滚到标记点。
begin;
update ky20 set score=33 where id=4;
select * from ky20;
begin;
update ky20 set score=score - 10 where id=5;
rollback; ##回滚
begin;
update ky20 set score=score - 9 where id=6;
savepoint s1;
update ky20 set score=score - 20 where id =8;
savepoint s2;
rollback to s1;
在MySQL中,当我们输入命令时,是系统在自动帮我们begin与commit,我们无需手动输入。这是因为mysql数据库默认设置了自动提交。
show variables like 'autocommit
#禁止自动提交(状态为OFF)
SET AUTOCOMMIT=0;
#开启自动提交,Mysql默认为1(状态为ON)
SET AUTOCOMMIT=1;
果没有开启自动提交,当前会话连接的MySQL的所有操作都会当成一个事务直到你输入rollback|commit,当前事务才算结束。当前事务结束前新的MySQL连接时无法读取到任何当前会话的操作结果。
2. 如果开启自动提交,MySQL会把每个SQL语句当成一个事务,然后自动的commit。
3. 当然无论开启与否,begin,commit,rollback,都是独立的事务。