在MySQL中设置事务隔离级别有2种方法:
1 在my.cnf中设置,在mysqld选项中如下设置
[mysqld]
transaction-isolation = READ-COMMITTED
2 在mysql窗口用set命令重置
- mysql> set global tx_isolation='REPEATABLE-READ';
- Query OK, 0 rows affected (0.01 sec)
- mysql>
查询当前的会话事务级别,可以使用:
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql>
查询全局的事务隔离级别,可以使用
- mysql> select @@global.tx_isolation;
- +-----------------------+
- | @@global.tx_isolation |
- +-----------------------+
- | READ-COMMITTED |
- +-----------------------+
- 1 row in set (0.00 sec)
- mysql>
在Serializable模式下。
- mysql> system cat /usr/local/mysql56m2/my.cnf |grep transaction-isolation
- transaction-isolation = READ-COMMITTED
- mysql>
复制二进制与隔离级别的关系
在SERIALIZABLE模式下,Innodb存储引擎会对每个select语句自动加Lock in sharedmode,给每一个读操作加共享锁。因此在这个隔离级别下,读占用锁了,一致性的非锁定读不再予以支持。因为Innodb存储引擎在 repeatable read 模式下就已经达到了3度的隔离,所以一般不在本地事务中使用serializable隔离级别,serializable的事务隔离级别主要用于 innodb存储引擎的分布式事务。
在Read committed的隔离模式下,除了唯一性约束检查以及外键约束检查需要Gap lock,innodb存储引擎不会使用gap lock的锁算法。不过使用read committed隔离级别需要注意一些问题,mysql5.1中,Read committed的事务隔离级别默认只能在replication的二进制为row格式下,如果二进制默认在statement模式下,则会报如下错 误:
- mysql> select @@version;
- +-------------+
- | @@version |
- +-------------+
- | 5.5.25a-log |
- +-------------+
- 1 row in set (0.00 sec)
- mysql>
- mysql> select @@binlog_format;
- +-----------------+
- | @@binlog_format |
- +-----------------+
- | STATEMENT |
- +-----------------+
- 1 row in set (0.00 sec)
- mysql> select @@tx_isolation;
- +-----------------+
- | @@tx_isolation |
- +-----------------+
- | REPEATABLE-READ |
- +-----------------+
- 1 row in set (0.00 sec)
- mysql> set tx_isolation='READ-COMMITTED';
- Query OK, 0 rows affected (0.00 sec)
- mysql> use test;
- Database changed
- mysql> create table a (b int, primary key (b)) engine=innodb;
- ERROR 1050 (42S01): Table 'a' already exists
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql> begin
- -> ;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into a select 100000;
- ERROR 1665 (HY000): Cannotexecute statement: impossible to write to binary log since BINLOG_FORMAT =STATEMENT and at least one table uses a storage engine limited to row-basedlogging. InnoDB is limited to row-logging when transaction isolation level isREAD COMMITTED or READ UNCOMMITTED.
ERROR 1665 (HY000):
Cannotexecute statement: impossible to write to binary log since
BINLOG_FORMAT =STATEMENT and at least one table uses a storage engine
limited to row-basedlogging. InnoDB is limited to
row-logging when transaction isolation level isREAD COMMITTED or READ
UNCOMMITTED.
[Note]:在mysql5.1以及mysql5.6模式下实验过都是如此。也许可以知道通过将innodb_locks_unsafe_for_binlog设置为1,来可以使binlog日志在statement下使用readcommitted的事务隔离级别:
- mysql> select @@innodb_locks_unsafe_for_binlog;
- +----------------------------------+
- | @@innodb_locks_unsafe_for_binlog |
- +----------------------------------+
- | 0 |
- +----------------------------------+
- 1 row in set (0.00 sec)
- mysql> set global innodb_locks_unsafe_for_binlog=1;
- ERROR 1238 (HY000): Variable 'innodb_locks_unsafe_for_binlog' is a readonly variable
- mysql>
此参数是只读模式,需要修改my.cnf重新启动才行。
在my.cnf里面的[mysqld]添加
[mysqld]
innodb_locks_unsafe_for_binlog = 1
然后重启,然后去check模仿一个事务操作,如下所示:
- mysql> select @@innodb_locks_unsafe_for_binlog;
- +----------------------------------+
- | @@innodb_locks_unsafe_for_binlog |
- +----------------------------------+
- | 1 |
- +----------------------------------+
- 1 row in set (0.00 sec)
- mysql>
- mysql> use test;
- Reading table information for completion of table and column names
- You can turn off this feature to get a quicker startup with -A
- Database changed
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql> begin;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into t select 15;
- Query OK, 1 row affected (0.00 sec)
- Records: 1 Duplicates: 0 Warnings: 0
- mysql> commit;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select * from t;
- +--------+
- | id |
- +--------+
- | 1 |
- | 12 |
- | 15 |
- | 11111 |
- | 111110 |
- +--------+
- 5 rows in set (0.00 sec)