技术开发 频道

浅析MySQL InnoDB数据库引擎


三、InnoDB表事务、隔离级别

1 事务

MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理,其他的类型是不支持的。InnoDB表事务控制我们在第三章介绍InnoDB引擎的时候已经给出过一个简单例子。InnoDB默认的是自动提交,我们在前边的例子中在事务开始的时候执行了BEGIN和SET AUTOCOMMIT=0操作来保证事务的可用性。MYSQL事务控制有两种方式:

(1) 用begin,rollback,commit来实现(显式)
begin *开始一个事务 rollback *事务回滚 commit *事务确认
(2)直接用set来改变mysql的自动提交模式(隐式)

MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们
可以通过:
set autocommit=0 *禁止自动提交 set autocommit=1 *开启自动提交
一个事务应用的简单例子:
mysql> CREATE TABLE t (id INT) TYPE=InnoDB; Query OK, 0 rows affected, 1 warning (0.45 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> insert into t values(1); Query OK, 1 row affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.08 sec) mysql> select * from t; Empty set (0.00 sec)
2 隔离级别

MYSQL提供四种事务隔离级别:

•序列化(SERIALIZABLE)
•可重复读(REPEATABLE READ)
•提交读(READ COMMITTED)
•未提交读(READ UNCOMMITTED)

未提交读——这通常称为 'dirty read':non-locking SELECT 的执行使我们不会看到一个记录的可能更早的版本;因而在这个隔离级别下是非 'consistent' reads;这级隔离级别的运作如同 READ COMMITTED。处于这个隔离级的事务可以读到其他事务还没有提交的数据。如果这个事务使用其他事务未提交的变化作为计算的基础,然后那些未提交的变化被他们的父事务撤销,则会导致误差。

提交读——在一个事务中已经COMMIT的数据可以在其他事务中看到。如果这个事务频繁提交的话,其他的大的查询事务中可能会得到多个不同的结果。

可重复读——这是 InnoDB 默认的事务隔离级。在一个事务中所有读都是连续的。

序列化——提供最大程度的隔离,如果每个事务都以这种隔离级运行就会影响Mysql的性能,因为需要大量的资源来使大量事务在任一时刻不被看到。如果一个事务在执行一个SELECT操作,另外的事务不允许执行UPDATE操作,这个隔离级别下的SELECT操作被阴式地转换为 SELECT ... LOCK IN SHARE MODE。

设置事务的隔离级别:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
需要super优先权执行这个操作。

取得当前事务的隔离级别:
mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.44 sec)
默认情况下,隔离级别变量的值是基于每个会话设置的,但是可以通过添加global关键字对所有的会话进行全局设置。

REPEATABLE READ级别事务一致读的例子(显式):

SESSION 1: 
mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> insert into t values(1); Query OK, 1 row affected (0.05 sec) mysql> select * from t; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec)
SESSION 2:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from t; Empty set (0.00 sec)
SESSION 1:
mysql> COMMIT; Query OK, 0 rows affected (0.08 sec)
SESSION 2:
mysql> select * from t; Empty set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec)
REPEATABLE READ级别事务一致读的例子(隐式):

SESSION 1: 
mysql> set autocommit=0; Query OK, 0 rows affected (0.01 sec) mysql> insert into t values(2); Query OK, 1 row affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.01 sec)
SESSION 2:
mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 0 | +--------------+ 1 row in set (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec)
SESSION 1:
mysql> commit; Query OK, 0 rows affected (0.06 sec) mysql> insert into t values(3); Query OK, 1 row affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.00 sec)
SESSION 2:
mysql> select * from t; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec)
SESSION 1:
mysql> commit; Query OK, 0 rows affected (0.06 sec) mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.05 sec)
SESSION 2:
mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> select * from t; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.00 sec)
0
相关文章