0001-MySQL中的事务

2019-01-24  本文已影响8人  即墨灯火

什么是事务?

事务就是一组应该一起成功或一起失败的SQL语句。事务应该具备原子性一致性隔离性持久性ACID)的属性。

注意:InnoDB支持事务处理,而MyISAM不支持事务处理。

如何启动一个事务(一组SQL)?

通过执行START TRANSACTION或BEGIN语句:

mysql> START TRANSACTION;

mysql> BEGIN;

接着,执行你希望在事务中包含的所有语句。确保所有语句执行成功后,执行COMMIT语句,该语句将完成事务并提交数据:

mysql> COMMIT;

如果遇到错误并希望中止事务,可以发送ROLLBACK语句而非COMMIT语句:

mysql> ROLLBACK;

autocommit

默认情况下,autocommit的状态时ON,这意味着所有单独的语句一旦被执行就会被提交,除非该语句在BEGIN……COMMIT块中。如果autocommit的状态为OFF,则需要明确发出COMMIT语句来提交事务。要禁用autocommit,请执行:

mysql> SET autocommit=0;

DDL语句,如数据库的CREATE或DROP语句,以及表或存储例程的CREATE,DROP或ALERT语句,都是无法回滚的。

部分语句,包括DDL语句、LOAD DATA INFILE、ANALYZE TABLE以及与replication相关的语句,会导致隐式COMMIT。

保存点

使用保存点可以回滚到事务中的某些点,而且无须中止事务。可以使用SAVEPOINT标识符为事务设置名称,并使用ROLLBACK TO标识语句将事务回滚到指定的保存点而不中止事务。

mysql> BEGIN;
...
mysql> SAVEPOINT transfer_to_b;
...
mysql> ROLLBACK TO transfer_to_b;
...
mysql> COMMIT;

隔离级别

当两个或多个事务同时发生时,隔离级别定义了一个事务与其他事务在资源或者数据修改方面的隔离级别。有四种类型的隔离级别,要更改隔离级别,需要设置tx_isolation变量,该变量是动态的并具有会话级别的作用范围。

如何修改

mysql> SET @@ transaction_isolation='READ-COMMITTED';

四种类型

可重复度需要重点了解一下。这种可重复读仅仅适用于SELECT语句,如果插入或修改某些行并提交该事务,那么从另一个并发REPEATABLE READ事务发出的DELETE或UPDATE语句,可能会影响那些刚刚提交的行,即使会话无法查询这些语句。如果事务更新或删除由不同事务提交的行,则这些更改对当前事务变为可见。

两种锁

其中,内部锁可以分为行级锁与表级锁,外部锁包括了READ与WRITE。

当会话中止,或执行UNLOCK TABLES时,所有锁都会被释放

如何使用

锁定表的语法

mysql> LOCK TABLES table_name [READ | WRITE]

要解锁表

mysql> UNLOCK TABLES;

要锁定所有数据库中的所有表,请执行以下语句。在获取数据库的一致快照时需要使用该语句,它会冻结对数据库的所有写入操作:

mysql> FLUSH TABLES WITH READ LOCK;

锁队列

除共享锁之外,没有两个锁可以一起加在一个表上。如果一个表已经有一个共享锁,此时有一个排他锁要进来,那么它将被保留在队列中,直到共享锁被释放。当排他锁在队列中时,所有后续的共享锁也会被阻塞并保留在队列中。

当InnoDB从表中读取/写入数据时会获取元数据锁。如果第二个事务请求WRITE LOCK,该事务将被保留在队列中,直到第一个事务完成。如果第三个事务想要读取数据,就必须等到第二个事务完成。

One More Thing

2018-01-23

上一篇下一篇

猜你喜欢

热点阅读