事务
ACID
ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency) 事务前后数据的完整性必须保持一致。
隔离性(Isolation) 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
具有ACID的特性的数据库支持强一致性,强一致性代表数据库本身不会出现不一致,每个事务是原子的,或者成功或者失败,事物间是隔离的,互相完全不影响,而且最终状态是持久落盘的,因此,数据库会从一个明确的状态到另外一个明确的状态,中间的临时状态是不会出现的,如果出现也会及时的自动的修复,因此是强一致的。
例子1
1、新建数据库RUNOOB。
2、选择SQL语句操作。
3、创建数据表。
命令:CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb;
4、每次操作之前需要清除上次执行的语句。
5、查询数据表。
命令:select * from runoob_transaction_test;
6、开始事务。
命令:begin;
7、在表中插入1行数据,值为5。
命令:insert into runoob_transaction_test value(5);
8、在表中插入1行值为6的数据。
命令:insert into runoob_transaction_test value(6);
9、提交事务。
命令:commit;
10、查询表。
命令:select * from runoob_transaction_test;
11、回滚。 命令:
begin; #开始事务
insert into runoob_transaction_test values(7); #插入值为7的数据
rollback; #回滚
select * from runoob_transaction_test; #查询表
commit; #提交事务
查询结果没有7的数据,因为执行了回滚,所以数据没有插入。
例子2
分别以dbadmin和命令行客户端执行事务与回滚操作:
实验1:在事务中向Student表插入一条记录,然后先后回滚、全表查询、事务提交
实验2:在事务中向Student表插入一条记录,然后先后全表查询、回滚、全表查询、事务提交
观察操作结果,并分析总结。
锁
在命令行客户端中(不能在sql操作界面中)将Course表加上读锁、Student表加上写锁,然后实验分别在两个表中增加一条记录和全表查询,观察操作结果,并分析总结。
mysql -uroot -p
mysql> lock table Course read;
mysql> lock table Student write;
死锁案例:
创建数据库
-
mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
-
Client A起事务,以share 锁模式读取数据
mysql> start transaction;
Query OK, 0 rows affected (0.03 sec)
mysql> SELECT * FROM t WHERE i = 1 lock in SHARE mode;
+------+
| i |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
- Client B另起事务,删除表t中的数据
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
上面的这个超时错将会在命令执行一段时间之后,才出现。其超时时间默认设置:
mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50 |
+--------------------------+-------+
1 row in set, 1 warning (0.03 sec)