详解MySQL与Spring的自动提交(autocommit)
1MySQL的autocommit设置
MySQL默认是开启自动提交的,即每一条DML(增删改)语句都会被作为一个单独的事务进行隐式提交。如果修改为关闭状态,则执行DML语句之后要手动提交才能生效。
查询当前会话的自动提交是否开启:
mysql>showvariableslike'autocommit'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|ON| +---------------+-------+
查询全局的自动提交是否开启:
mysql>showglobalvariableslike'autocommit'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|ON| +---------------+-------+
通过修改autocommit变量可以关闭和开启操作
关闭当前会话的自动提交模式 mysql>setautocommit=0; mysql>showvariableslike'autocommit'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|OFF| +---------------+-------+ 全局的autocommit还是开启状态 mysql>showglobalvariableslike'autocommit'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|ON| +---------------+-------+ 关闭全局的autocommit mysql>setglobalautocommit=0; mysql>showglobalvariableslike'autocommit'; +---------------+-------+ |Variable_name|Value| +---------------+-------+ |autocommit|OFF| +---------------+-------+
如果想要MySQL服务重启之后仍能生效,需要设置系统环境变量。MySQL5.7在cnf配置文件中[mysqld]下面设置autocommit的值。
[mysqld] ... autocommit=0
Spring中对自动提交的控制
MySQL的JDBC驱动包mysql-connector-java会给会话的connection默认开启自动提交,譬如mysql-connector-java-8.0.22版本的代码:
//com.mysql.cj.protocol.a.NativeServerSession.java privatebooleanautoCommit=true;
常用的数据库连接池如HikariCP,druid等,默认也是开启自动提交,会将connection的自动提交设置都改为true。
druid在初始化DataSource的时候设置connection的autocommit为true。代码如下:
com.alibaba.druid.pool.DruidAbstractDataSource.java protectedvolatilebooleandefaultAutoCommit=true; ... publicvoidinitPhysicalConnection(Connectionconn,Mapvariables,Map globalVariables)throwsSQLException{ if(conn.getAutoCommit()!=defaultAutoCommit){ //将connection的autocommit设置为true conn.setAutoCommit(defaultAutoCommit); } ... }
HikariCP初始化DataSource的默认配置中autocommit也是true:
com.zaxxer.hikari.HikariConfig.java publicHikariConfig() { ... isAutoCommit=true; }
对于事务管理器PlatformTransactionManager管理的显式事务(譬如@Transactional注解声明)在开启事务时会关闭自动提交模式。代码如下:
@Override protectedvoiddoBegin(Objecttransaction,TransactionDefinitiondefinition){ DataSourceTransactionObjecttxObject=(DataSourceTransactionObject)transaction; Connectioncon=null; try{ ........ //Switchtomanualcommitifnecessary.ThisisveryexpensiveinsomeJDBCdrivers, //sowedon'twanttodoitunnecessarily(forexampleifwe'veexplicitly //configuredtheconnectionpooltosetitalready). if(con.getAutoCommit()){ txObject.setMustRestoreAutoCommit(true); if(logger.isDebugEnabled()){ logger.debug("SwitchingJDBCConnection["+con+"]tomanualcommit"); } //关闭自动提交模 con.setAutoCommit(false); } ....... } catch(Throwableex){ ....... } }
总结
MySQL的autocommit模式默认是打开状态,为了防止手动的DML操作导致失误,生产环境可以设置为默认关闭的状态。一般的jdbc连接池默认都是开启状态,而且是可配置的。显式事务下会设置成关闭状态,单纯的修改数据库环境的autocommit不会对代码的行为产生影响。
以上就是详解MySQL与Spring的自动提交(autocommit)的详细内容,更多关于MySQL自动提交(autocommit)的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。