本文共 2797 字,大约阅读时间需要 9 分钟。
1. 概念
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
2. 操作
1. 开启事务: start transaction;2. 回滚: rollback;3. 提交: commit;
3. 例子
CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), balance DOUBLE);-- 添加数据INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
当我们想修改表中的数据,假设将张三中的五百转给李四,我们执行
1.张三的钱-500UPDATE account SET balance = balance-500 WHERE NAME = 'zhangsan';2.李四的钱+500UPDATE account SET balance = balance+500 WHERE NAME = 'lisi';
这样是不会出现任何问题的,但是当我们在执行操作的过程中,如果出现错误,我们人为设置错误操作如下:
update account set balance = balance-500 where name = 'zhangsan';这里要出错...update account set balance = balance+500 where name = 'lisi';
这个时候,张三的钱-500,然而李四的钱并没有变化。这就产生了错误,是不正常的。如何解决这些问题,我们就用到了事务管理。
还是上面的例子,如果我们开启事物,发生错误的时候会产生怎样的效果?
START TRANSACTION;UPDATE account SET balance = balance-500 WHERE NAME = 'zhangsan';这里要出错UPDATE account SET balance = balance+500 WHERE NAME = 'lisi';
我们发现在当前窗口下数据发生了改变,但是当我们重新打开一个窗口,查询表中数据,我们发现,数据并没有改变,也就是产生错误的时候,表中数据并没有改变。
上表中数据临时发生改变,我们说这只是临时的,在磁盘中并没有改变数据,当我们发现数据错误以后,我们使用回滚语句,回到事物开启前的状态。
ROLLBACK;
这个时候我们再查询表中数据,我们发现表已经回到原来的状态。
如果我们在执行完操作以后发现数据并没有发生变化,我们就可以提交数据
commit;
注意:提交或者回滚数据以后,磁盘中的数据就发生了变化。
事务提交的两种方式:
修改事务的默认提交方式:
查看事务的默认提交方式:
~~~mysqlSELECT @@autocommit; -- 1 代表自动提交 0 代表手动提交 ~~~
修改默认提交方式:
set @@autocommit = 0;
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
持久性:当事务提交或回滚后,数据库会持久化的保存数据。
隔离性:多个事务之间。相互独立。
一致性:事务操作前后,数据总量不变
1. 概念:
多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
2. 存在问题:
1. **脏读:一个事务,读取到另一个事务中没有提交的数据** 2. **不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。** 3. **幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。**
隔离级别
注意:
隔离级别从小到大安全性越来越高,但是效率越来越低
数据库查询隔离级别∶
select @@tx_isolation;
数据库设置隔离级别:
set global transaction isolation level 级别字符串;
我们首先设置隔离级别
set global transaction isolation level read uncommitted;
我们开启两个窗口,在其中一个窗口中修改数据,在未提交的时候会发现在另一个事物中会查看到修改的数据,这就说明此时产生了脏读数据,在另一个事物中,在前一事物修改前,读出修改前的数据,在前一事物修改后,又读出一组数据,前后读取的数据不一致的这种情况就称之为读取数据没有重复,也就是不可重复读数据。
set global transaction isolation level read committed;
我们打开两个窗口,在其中一个窗口中修改数据,此时在未提交数据的时候我们会发现在另一事物数据并不会发生任何变化,只有在前一事物提交数据以后才能查看到变化,这就说明,此时已经没有了脏读的问题,因为前一事物不提交数据,后一事物不会发生变化,但是此时会产生在后一事物关闭事物前,前后读取的数据不一致的问题,也就是产生了不可重复读数据的问题。
set global transaction isolation level repeatable read;
我们打开两个敞口,开启两个事物,我们发现即使前一事物关闭事物,在后一事物中也不会看到任何变化,只有在后一事物也关闭事物以后我们才能看到数据的变化,这就解决了脏读和不可重复读的问题。
set global transaction isolation level serializable;
这是我们发现,两个事物中,如果前一事物不提交或者回滚,后一事物额操作是执行不下去的。这就解决了所有的问题。
转载地址:http://zboen.baihongyu.com/