mysql的autocommit

<p>autocommit的测试</p><p>对于innodb表:</p><p>首先创建两个innodb表:</p><pre class="brush:sql;toolbar:false">mysql&gt;createtabletab_kx(aintauto_increment,primarykey(a)); QueryOK,0rowsaffected(0.16sec) mysql&gt;createtabletab_kx2(aintauto_increment,primarykey(a)); QueryOK,0rowsaffected(0.17sec)</pre><p>在session1,设置autocommit为OFF:</p><pre class="brush:sql;toolbar:false">mysql&gt;setautocommit=0; QueryOK,0rowsaffected(0.00sec) mysql&gt;showvariableslike&#39;%autocommit%&#39;; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|OFF| +---------------+-------+ 1rowinset(0.00sec)</pre><p>在session2设置autocommit为ON:</p><pre class="brush:sql;toolbar:false">mysql&gt;showvariableslike&#39;%autocommit%&#39;; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|ON| +---------------+-------+ 1rowinset(0.00sec)</pre><p>在session1,对tab_kx插入三行数据但不提交:</p><pre class="brush:sql;toolbar:false">mysql&gt;insertintotab_kxvalues(&#39;&#39;); QueryOK,1rowaffected,1warning(0.00sec) mysql&gt;insertintotab_kxvalues(&#39;&#39;); QueryOK,1rowaffected,1warning(0.00sec) mysql&gt;insertintotab_kxvalues(&#39;&#39;); QueryOK,1rowaffected,1warning(0.00sec) mysql&gt;select*fromtab_kx; +---+ |a| +---+ |1| |2| |3| +---+ 3rowsinset(0.00sec) mysql&gt;select*fromtab_kx2; Emptyset(0.00sec)</pre><p>此时查看session2是否可以看到这三行数据:</p><pre class="brush:sql;toolbar:false">mysql&gt;select*fromtab_kx; Emptyset(0.00sec)</pre><p>【说明】,session2看不到其他session没有提交的DML;</p><p>此时在session2插入四行数据到表tab_kx2(由于是auto commit的,所以不需要提交):</p><pre class="brush:sql;toolbar:false">mysql&gt;insertintotab_kx2values(); QueryOK,1rowaffected(0.07sec) mysql&gt;insertintotab_kx2values(); QueryOK,1rowaffected(0.04sec) mysql&gt;insertintotab_kx2values(); QueryOK,1rowaffected(0.04sec) mysql&gt;insertintotab_kx2values(); QueryOK,1rowaffected(0.02sec) mysql&gt;select*fromtab_kx2; +---+ |a| +---+ |1| |2| |3| |4| +---+ 4rowsinset(0.00sec)</pre><p>【注意】但此时session1仍然看不到tab_kx2的数据,</p><p>mysql&gt; select * from tab_kx2;</p><p>Empty set (0.00 sec)</p><p>当手动执行commit时,才可以看到这些数据,同时session2也可以看到tab_kx表的数据。</p><pre class="brush:sql;toolbar:false">mysql&gt;commit; QueryOK,0rowsaffected(0.03sec) mysql&gt;select*fromtab_kx2; +---+ |a| +---+ |1| |2| |3| |4| +---+ 4rowsinset(0.00sec)</pre><p>【结论】对于autocommit为OFF的session,其事务开始时间点之后发生的DML操作对其都是不可见的,只有当事务结束时才可见。(其他session的DDL即时可见)</p><p>另外,如果其session执行了一个DDL,会隐式提交之前的事务,DML的修改其他session可见了。</p><p>但有意思的是,当我一个session中对tab_kx表drop的时候,会话被阻塞了(如果隐式提交了,应该不会发生这种情况),在另个session中执行读,也被阻塞了</p><p>此时我在原来的session(autocommit为OFF)执行显示提交commit:</p><p>其他session都被&quot;激活&quot;了,而且是按执行顺序激活的。</p><p>myisam表:</p><p>创建两个myisam表,</p><pre class="brush:sql;toolbar:false">mysql&gt;createtabletab_kx(aintauto_increment,primarykey(a))engine=myisam; QueryOK,0rowsaffected(0.05sec) mysql&gt;createtabletab_kx2(aintauto_increment,primarykey(a))engine=myisam; QueryOK,0rowsaffected(0.05sec) 在session1,(autocommit为OFF)插入三行数据, mysql&gt;insertintotab_kxvalues(); QueryOK,1rowaffected(0.00sec) mysql&gt;insertintotab_kxvalues(); QueryOK,1rowaffected(0.00sec) mysql&gt;insertintotab_kxvalues(); QueryOK,1rowaffected(0.00sec) mysql&gt;select*fromtab_kx; +---+ |a| +---+ |1| |2| |3| +---+ 3rowsinset(0.00sec) 在其他session中查询tab_kx, mysql&gt;select*fromtab_kx; +---+ |a| +---+ |1| |2| |3| +---+ 3rowsinset(0.00sec)</pre><p>可以看到结果,这与innodb的表不同;不需要显示提交,DML修改就可以对外可见了。</p><p>【结论】myisam是非事务的存储引擎,commit是对事物有效的,所以没啥作用。</p><p>【注意】但当我对tab_kx做删除时,会话被阻塞,尽管没有事务性,但autocommit=OFF仍然在起作用,虽然不再持有表锁;</p><p>在session1执行显示提交commit,立刻解锁,阻塞的会话被激活。</p><p>注:mysql官方文档如是说:</p><p>ALTER TABLE运行时会对原表进行临时复制,在副本上进行更改,然后删除原表,再对新表进行重命名。在执行ALTER TABLE时,其它用户可以阅读原表,但是对表的更新和修改的操作将被延迟,直到新表生成为止。新表生成后,这些更新和修改信息会自动转移到新表上。</p><p></p>
RangeTime:0.006627s
RangeMem:211.56 KB
返回顶部 留言