总是有点弄不清楚mysql 的 uncommit 和commit的区别,今天测试了一下。
1,事务是竞争资源的基本单位(即锁)。
2,两个并发事务对于同一张表操作(会加锁的操作),如果使用的是同一个索引,但是不是相同的记录,打印结果发现不会有阻塞的情况。也许是对不同的记录不阻塞,但是不知道2个事务请求索引的时侯是否阻塞其中1个?????
例子如下:(id列有索引)时间上依次如下执行:
--------------------------------
事务1开始,事务2开始;
事务1: update table set age=1 where id=1;//(1)
事务2: select age from table where id=2 for update;//(2)
事务1: update table set age=2 where id=1;//(3)
事务1提交;事务2提交;
-------------------------------------
其中执行过程是(1)(2)(3)
如果事务2查询的id是1 那么执行过程为(1)(3)(2),因为id为1的记录已经被事务1加锁。
3,对于update,select ... for update,select ... for语句,不论当前是uncommit 还是commit级别都遵守加锁排斥的原则。
不论行锁还是表锁,都会有竞争,如果当前行或者表有锁,则会根据排他锁共享锁原则判断能否加锁而决定当前事务是等待锁而阻塞还是加锁执行
4,对于select操作,不加任何锁,如果当前是uncommit,则会读到别的事务没有提交的脏数据;如果是commit则只读到提交的数据,这个select操作不会因为事务级别而阻塞。
例子如下:(id列有索引,id为1 的用户age为10)时间上依次如下执行:
--------------------------------
事务1开始,事务2开始;
事务1: update table set age=1 where id=1;//(1)
事务2: select age from table where id=1;//(2)
事务1: update table set age=2 where id=1;//(3)
事务1提交;事务2提交;
-------------------------------------
如果为uncommit 则 事务2得到结果为1;如果为commit 则结果为10
两种情况事务(2)不会阻塞,执行结果依次为 (1)(2)(3)
个人感觉:uncommit 和commit 只是针对 select 有作用,如果select 的时候使用的共享锁(share mode)或者排他锁(for update) 这2种事务没有差别。不过对于uncommit下 select 能够读到脏数据很好奇!
不知道理解对不对,欢迎大家指正,谢谢!
2009年11月29日 13:09