<p>autocommit</p><p>一、概念</p><p>事务自动提交设置,默认为1,即除非显示声明一个事务的开始,否则每一个查询都会被当做独立的事务被处理</p><p>默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则隐式的提交事务,如果执行失败则隐式的回滚事务</p><p>关闭自动提交的原因,事务作为一个独立处理最小单元,往往需要处理一系列连续的数据操作,这些操作被视为一个整体,需要同时成功或同时失败,而不能其中某个操作成功;比如:A汇款给B,B接收到歀;即 A的账户扣款,而B的账户增加;必须同时成功或同时失败;如果成功则commit否则整体回滚;批量数据提交,如果提交1000条数据操作,需要处理1000次提交commit,而如果关闭autocommit等1000条数据处理完毕后统一一次提交</p><p>存储引擎需支持事务,如InnoDB,而MyISAM不支持事务</p><p>事务是否开启:如果没有显示的开启事务,autocommit 才会生效;</p><p>// 示例</p><p>// descrpiton:在显示开启事务的情况下,无论是否开启自动提交,下面示例均会发生</p><p>// 结论:在显示开启事务的情况下,autocommit 不生效</p><pre class="brush:sql;toolbar:false">//console1 mysql&gt;begin; QueryOK,0rowsaffected mysql&gt;select*fromt_order; +----+-------+--------------+--------+ |id|name|order_no|status| +----+-------+--------------+--------+ |1|订单1|DD_000000001|1| |2|订单2|DD_000000002|2| |3|订单3|DD_000000003|3| +----+-------+--------------+--------+ mysql&gt;updatet_ordersetorder_no=&quot;DD_000000033&quot;whereid=3; QueryOK,1rowaffected mysql&gt;select*fromt_order;//修改结果当前会话中的当前事务可见 +----+-------+--------------+--------+ |id|name|order_no|status| +----+-------+--------------+--------+ |1|订单1|DD_000000001|1| |2|订单2|DD_000000002|2| |3|订单3|DD_000000033|3| +----+-------+--------------+--------+ 3rowsinset</pre><pre class="brush:sql;toolbar:false">//console2 mysql&gt;select*fromt_order;//不可见 +----+-------+--------------+--------+ |id|name|order_no|status| +----+-------+--------------+--------+ |1|订单1|DD_000000001|1| |2|订单2|DD_000000002|2| |3|订单3|DD_000000003|3| +----+-------+--------------+--------+</pre><p>3 rows in set</p><pre class="brush:sql;toolbar:false">//console1 mysql&gt;commit; QueryOK,0rowsaffected //console2 mysql&gt;select*fromt_order; +----+-------+--------------+--------+ |id|name|order_no|status| +----+-------+--------------+--------+ |1|订单1|DD_000000001|1| |2|订单2|DD_000000002|2| |3|订单3|DD_000000033|3| +----+-------+--------------+--------+ 3rowsinset</pre><p>二、基本操作</p><pre class="brush:sql;toolbar:false">//查询 mysql&gt;SELECT@@autocommit; +--------------+ |@@autocommit| +--------------+ |1| +--------------+ 1rowinset mysql&gt;SHOWVARIABLESLIKE&quot;%AUTOCOMMIT%&quot;; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|ON| +---------------+-------+ 1rowinset //修改 mysql&gt;SETautocommit=0; QueryOK,0rowsaffected //在当前session关闭autocommit: mysql&gt;set@@session.autocommit=0; QueryOK,0rowsaffected(0.00sec) //在global级别关闭autocommit: mysql&gt;set@@global.autocommit=0; QueryOK,0rowsaffected(0.01sec)</pre><p>三、产生的问题</p><p>示例:</p><p>// 系统准备</p><p>// MySQL:Server version: 5.7.17 ;</p><p>// 查询MySQL版本:CMD 命令,输入mysql,回车进入命令行,根据系统提示,即可查看当前安装版本</p><p>// 数据连接工具:Navicat for MySQL</p><p>// F6命令打开两个console窗口,模拟两个不同的connection</p><p>----------</p><pre class="brush:sql;toolbar:false"><br/></pre><pre class="brush:sql;toolbar:false">mysql&gt;COMMIT; QueryOK,0rowsaffected //T4时间console2 mysql&gt;SELECT*FROMT_ORDERWHEREID=3; //在console1提交事务后查询结果依旧没有改变 +----+-------+--------------+--------+ |id|name|order_no|status| +----+-------+--------------+--------+ |3|订单3|DD_000000003|3| +----+-------+--------------+--------+ 1rowinset //T5时间console2 //查询到最新数据的方式 //1.执行commit;当前事务结束;否则再次查询仍然与上次的查询在一个事务中,查询是上次查询结果的快照; //2.SETautocommit=1;每次操作都是一个独立的原子性的操作,自动提交,每次都是一个独立的事务</pre><p>结论:</p><p>使用时应注意,在需要关闭自动提交的操作前将 autocommit = 0 操作完毕后,再将其改为 autocommit = 1 ;</p><p>在关闭AutoCommit的条件下,console 1 在T1和T2两个时间点执行的SQL语句其实在一个事务里,因此每次读到的其实只是一个快照,即一致性非阻塞读:InnoDB通过MVCC机制表示数据库某一时刻的查询快照,查询可以看该时刻之前提交的事务所做的改变,但是不能看到该时刻之后或者未提交事务所做的改变。但是,查询可以看到同一事务中之前语句所做的改变</p><p>未起作用</p><p>连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect=&#39;SET autocommit=0&#39;根本不会启作用,也不会报任何错误</p><p>显示开启事务</p><p>注意:</p><p>1、不能将&quot;关闭autocommit&quot;作为缺省设置,否则在 innodb 表上执行的查询操作也将因为没有执行 commit 或者 rollback 而一直锁表!因此只能在需要时局部关闭 autocommit,并在操作完成后开启 autocommit</p><p>2、连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect=&#39;SET autocommit=0&#39;根本不会启作用,也不会报任何错误</p><p>If a user has SUPER privilege, init_connect will not execute,(otherwise if init_connect will a wrong query no one can connect to server).</p><p>Note, if init_connect is a wrong query, the connection is closing without any errors and next command will clause &#39;lost connection&#39; error.</p>
返回顶部 留言