mysql默认配置 innodb存储引擎
CREATE TABLE `t_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8;
启动两个session S1 和 S2;
insert:
实验1:delete from t_test;
ALTER TABLE `t_test` AUTO_INCREMENT = 1;
S1: begin;
insert into t_test set version = 1; --> 执行成功
select * from t_test; --> 查出被插入的数据 id 1
S2 : select * from t_test; -->执行成功 无数据
insert into t_test set version = 1; --> 执行成功
select * from t_test; --> 查出 id = 2 的数据 说明S1中插入的数据没有读取到,事务的隔离性正确。
S1 : select * from t_test; -->查出 id = 1 的数据,说明S2中插入的数据没有读取到,事务的隔离性正确。
commit;
select * from t_test; -->查出 id = 1,2 的数据,说明S2中插入的数据读取到,事务的隔离性正确。
S2: select * from t_test; -->查出 id = 1,2 的数据,说明S1中插入的数据读取到,事务的隔离性正确。
实验2:
delete from t_test;
ALTER TABLE `t_test` AUTO_INCREMENT = 1;
S1: begin;
insert into t_test set version = 1; --> 执行成功
select * from t_test; --> 查出被插入的数据 id 1
S2 : select * from t_test; -->执行成功 无数据
begin;
insert into t_test set version = 1; --> 执行成功
select * from t_test; --> 查出 id = 2 的数据 说明S1中插入的数据没有读取到,事务的隔离性正确。
S1 : select * from t_test; -->查出 id = 1 的数据,说明S2中插入的数据没有读取到,事务的隔离性正确。
commit;
select * from t_test; -->查出 id = 1 的数据,说明S2中插入的数据没读取到,事务的隔离性正确。
S2: select * from t_test; -->查出 id = 2 的数据,说明S1中插入的数据没读取到,事务的隔离性正确。
rollback;
select * from t_test; -->查出 id = 1的数据,说明S1中插入的数据读取到,事务的隔离性正确。
S1: select * from t_test; -->查出 id = 1的数据,说明S1中插入的数据读取到,事务的隔离性正确。
总结:sql的插入操作没有锁表和锁记录相关的操作。
update:实验步骤比较麻烦,不想详细记录了。这里总结一下实验结果。
1.在默认配置下,sql_safe_update=1,所以update条件中必须带有主键id,不论条件中是否还有其他的字段,都是行级锁。
2.在S1中启动事务,执行update操作,S2中update同一条记录会等待S1执行完毕之后才能继续,S2中在这之后的SQL都处于等待中。
3,.set sql_safe_update = 0,允许不根据主键id来update数据,此时mysql执行表级锁
4.由于update存在行级锁,在启动事务时要注意死锁问题。
最后:mysql autocommit = 1; 即自动提交。如果启动事务,自动提交机制会被自动屏蔽。