详解MySQL与Spring的自动提交(autocommit)

1 MySQL的autocommit设置

MySQL默认是开启自动提交的,即每一条DML(增删改)语句都会被作为一个单独的事务进行隐式提交。如果修改为关闭状态,则执行DML语句之后要手动提交 才能生效。
查询当前会话的自动提交是否开启:

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit  | ON  |
+---------------+-------+

查询全局的自动提交是否开启:

mysql> show global variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit  | ON  |
+---------------+-------+

通过修改autocommit变量可以关闭和开启操作

关闭当前会话的自动提交模式
mysql> set autocommit=0;

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit  | OFF  |
+---------------+-------+

 全局的autocommit还是开启状态
mysql> show global variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit  | ON  |
+---------------+-------+

 关闭全局的autocommit
mysql> set global autocommit=0;

mysql> show global variables like '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
  private boolean autoCommit = true;

常用的数据库连接池 如HikariCP,druid等,默认也是开启自动提交,会将connection的自动提交设置都改为true。
druid在初始化DataSource的时候设置connection的autocommit为true。代码如下:

com.alibaba.druid.pool.DruidAbstractDataSource.java
  protected volatile boolean             defaultAutoCommit             = true;
  ...
  public void initPhysicalConnection(Connection conn, Map<String, Object> variables, Map<String, Object> globalVariables) throws SQLException {
    if (conn.getAutoCommit() != defaultAutoCommit) {
      //将connection的autocommit设置为true
      conn.setAutoCommit(defaultAutoCommit);
    }
    ...

  }

HikariCP 初始化DataSource的默认配置 中autocommit也是true:

com.zaxxer.hikari.HikariConfig.java
  public HikariConfig()
  {
   ...
   isAutoCommit = true;
  }

对于事务管理器PlatformTransactionManager管理的显式事务(譬如@Transactional注解声明)在 开启事务时会关闭自动提交模式。 代码如下:

	@Override
	protected void doBegin(Object transaction, TransactionDefinition definition) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
      		........

			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
			// so we don't want to do it unnecessarily (for example if we've explicitly
			// configured the connection pool to set it already).
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
                //关闭自动提交模
                con.setAutoCommit(false);
			}

      		.......
		}

		catch (Throwable ex) {
     		.......
		}
	}

总结

MySQL的autocommit模式默认是打开状态,为了防止手动的DML操作导致失误,生产环境可以设置为默认关闭的状态。一般的jdbc 连接池默认都是开启状态,而且是可配置的。显式事务下会设置成关闭状态,单纯的修改数据库环境的autocommit不会对代码的行为产生影响。

以上就是详解MySQL与Spring的自动提交(autocommit)的详细内容,更多关于MySQL 自动提交(autocommit)的资料请关注我们其它相关文章!

(0)

相关推荐

  • mysql实现事务的提交和回滚实例

    mysql创建存储过程的官方语法为: 复制代码 代码如下: START TRANSACTION | BEGIN [WORK]COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]SET AUTOCOMMIT = {0 | 1} 我这里要说明的mysql事务处理多个SQL语句的回滚情况.比如说在一个存储过程中启动一个事务,这个事务同时往三个表中插入数据,每插完一张表需要

  • mysql实现事务的提交与回滚的实例详解

    最近要对数据库的数据进行一个定时迁移,为了防止在执行过程sql语句因为某些原因报错而导致数据转移混乱,因此要对我们的脚本加以事务进行控制. 首先我们建一张tran_test表 CREATE TABLE tran_test( f1 VARCHAR(10) NOT NULL, f2 INT(1) DEFAULT NULL, PRIMARY KEY (f1) )ENGINE=INNODB CHARSET=utf8 我想对tran_test插入两条数据,但是为了防止插入中报错,因此我要把插入语句控制在一

  • python连接mysql并提交mysql事务示例

    复制代码 代码如下: # -*- coding: utf-8 -*-import sysimport MySQLdbreload(sys)sys.setdefaultencoding('utf-8')class DB(object): def __init__(self,host='127.0.0.1',port=3306,user='root',passwd='123',database=''):  self.__host=host  self.__port=port  self.__user

  • MySQL找出未提交事务的SQL实例浅析

    很久之前曾经总结过一篇博客"MySQL如何找出未提交事务信息",现在看来,这篇文章中不少知识点或观点都略显肤浅,或者说不够深入,甚至部分结论是错误的.下面重新探讨一下这个话题.那么我们还是以之前的例子来介绍. --准备测试环境数据(实验环境为MySQL 8.0.18社区版) mysql> create table kkk(id int , name varchar(12)); Query OK, 0 rows affected (0.34 sec) mysql> inser

  • php将textarea数据提交到mysql出现很多空格的解决方法

    本文实例讲述了php将textarea数据提交到mysql出现很多空格的解决方法.分享给大家供大家参考.具体分析如下: 有一些朋友可能会发现我们在html提交给php处理保存数据到mysql中之后会发现我们再次从mysql读出数据时会有很多的空格了,那么我们如果直接在mysql中查看又没有空间,这是什么问题要如何处理呢. textarea中总是有很多空格问题解决 问题描述: 在php读取mysql数据到textarea中开头可结尾总有很多空格,在数据表中查看数据是没有空格的. 问题原因: 内容应

  • Mysql事务隔离级别之读提交详解

    查看mysql 事务隔离级别 mysql> show variables like '%isolation%'; +---------------+----------------+ | Variable_name | Value | +---------------+----------------+ | tx_isolation | READ-COMMITTED | +---------------+----------------+ 1 row in set (0.00 sec) 可以看到

  • JSP+ MySQL中文乱码问题post提交乱码解决方案

    写了两个jsp页面index.jsp和mysql_insert.jsp.数据处理流程为:在浏览器(chrome)上访问index.jsp后在其表单上输入数据,提交至mysql_insert.jsp,mysql_insert.jsp首先将接收到的数据按变量存入MySQL的html_db数据库的person_tb中(该表原有部分数据),然后mysql_insert.jsp再拿出该表中所有数据显示在mysql_insert.jsp页面上. 现在发现,当提交的数据中含有中文(比如变量姓名的值为中文)时,

  • 探究MySQL中索引和提交频率对InnoDB表写入速度的影响

    本次,我们来看看索引.提交频率对InnoDB表写入速度的影响,了解有哪些需要注意的. 先直接说几个结论吧: 1.关于索引对写入速度的影响: a.如果有自增列做主键,相对完全没索引的情况,写入速度约提升 3.11%: b.如果有自增列做主键,并且二级索引,相对完全没索引的情况,写入速度约降低 27.37%: 因此,InnoDB表最好总是有一个自增列做主键. 2.关于提交频率对写入速度的影响(以表中只有自增列做主键的场景,一次写入数据30万行数据为例): a.等待全部数据写入完成后,最后再执行com

  • MySQL找出未提交事务信息的方法分享

    前阵子,我写了一篇博客"ORACLE中能否找到未提交事务的SQL语句", 那么在MySQL数据库中,我们能否找出未提交事务执行的SQL语句或未提交事务的相关信息呢? 实验验证了一下,如果一个会话(连接)里面有一个未提交事务,然后不做任何操作,那么这个线程处于Sleep状态 mysql> select connection_id() from dual; +-----------------+ | connection_id() | +-----------------+ | 6

  • 详解MySQL与Spring的自动提交(autocommit)

    1 MySQL的autocommit设置 MySQL默认是开启自动提交的,即每一条DML(增删改)语句都会被作为一个单独的事务进行隐式提交.如果修改为关闭状态,则执行DML语句之后要手动提交 才能生效. 查询当前会话的自动提交是否开启: mysql> show variables like 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit

  • 详解MySQL连接挂死的原因

    一.背景 近期由测试反馈的问题有点多,其中关于系统可靠性测试提出的问题令人感到头疼,一来这类问题有时候属于"偶发"现象,难以在环境上快速复现:二来则是可靠性问题的定位链条有时候变得很长,极端情况下可能要从 A 服务追踪到 Z 服务,或者是从应用代码追溯到硬件层面. 本次分享的是一次关于 MySQL 高可用问题的定位过程,其中曲折颇多但问题本身却比较有些代表性,遂将其记录以供参考. 架构 首先,本系统以 MySQL 作为主要的数据存储部件.整一个是典型的微服务架构(SpringBoot

  • 详解MySQL批量入库的几种方式

    目录 1. MySQL批量入库概述 2. Hutool封装jdbc方式 测试环境准备 3. Jdbc直接或批量执行方式 4. MyBatis批量入库方式 5. MySQL批量入库总结 1. MySQL批量入库概述 最近压测一款mysql持久化工具,目前市面上mysql批量入库方式有很多,这里分别对常用的几种方式进行压测对比分析,比如列举了hutool工具封装的jdbc方式,jdbc直接执行与批量执行的方式,以及常用的mybatis方式. 2. Hutool封装jdbc方式 Hutool-db是一

  • 详解MySQL 慢查询

    查询mysql的操作信息 show status -- 显示全部mysql操作信息 show status like "com_insert%"; -- 获得mysql的插入次数; show status like "com_delete%"; -- 获得mysql的删除次数; show status like "com_select%"; -- 获得mysql的查询次数; show status like "uptime";

  • 详解 Mysql 事务和Mysql 日志

    事务特性 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱,B却没收到. 3.隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰.比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账. 4.持久性(Durability):事务完成后,事务对数据库的所有更新

  • 详解mysql 中的锁结构

    Mysql 支持3中锁结构 表级锁,开销小,加锁快,不会出现死锁,锁定的粒度大,冲突概率高,并发度最低 行级锁,开销小,加锁慢,会出现死锁,锁定粒度小,冲突概率最低,并发度最高 页面锁,开销和加锁处于表锁和行锁之间,会出现死锁,锁粒度基于表和行之间,并发一般 InnoDB锁问题 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.  行级锁和表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题. InnoDB的行锁模式及加锁方法 Inn

  • 详解MySQL中事务隔离级别的实现原理

    前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什么要有四个隔离级别. 今天我们就先来聊聊MySQL中事务的隔离性的实现原理,后续还会继续出文章分析其他特性的实现原理. 当然MySQL博大精深,文章疏漏之处在所难免,欢迎批评指正. 说明 MySQL的事务实现逻辑是位于引擎层的,并且不是所有的引擎都支持事务的,下面的说明都是以InnoDB引擎为基准.

  • 详解MySQL 幻读及如何消除

    这是一篇数据库隔离级别的科普文章,旨在了解数据库中著名的幻读现象,为了专注,对脏读.不可重复读不作讨论. 事务隔离级别 MySQL有四级事务隔离级别: 读未提交 READ-UNCOMMITTED: 存在脏读,不可重复读,幻读的问题 读已提交 READ-COMMITTED:不存在脏读,但存在不可重复读,幻读问题 可重复读 REPEATABLE-READ:不存在脏读,不可重复读问题,但存在幻读问题 序列化SERIALIZABLE:解决脏读,不可重复读,幻读问题,但完全串行执行,性能最低 什么是幻读

  • 详解MySQL的半同步

    前言 年后在进行腾讯二面的时候,写完算法的后问的第一个问题就是,MySQL的半同步是什么?我当时直接懵了,我以为是问的MySQL的两阶段提交的问题呢?结果确认了一下后不是两阶段提交,然后面试官看我连问的是啥都不知道,就直接跳过这个问题,直接聊下一个问题了.所以这次总结一下这部分的知识内容,文字内容比较多,可能会有些枯燥,但对于这方面感兴趣的人来说还是比较有意思的. MySQL的主从复制 我们的一般在大规模的项目上,都是使用MySQL的复制功能来创建MySQL的主从集群的.主要是可以通过为服务器配

  • 详解MySQL数据库千万级数据查询和存储

    百万级数据处理方案 数据存储结构设计 表字段设计 表字段 not null,因为 null 值很难查询优化且占用额外的索引空间,推荐默认数字 0. 数据状态类型的字段,比如 status, type 等等,尽量不要定义负数,如 -1.因为这样可以加上 UNSIGNED,数值容量就会扩大一倍. 可以的话用 TINYINT.SMALLINT 等代替 INT,尽量不使用 BIGINT,因为占的空间更小. 字符串类型的字段会比数字类型占的空间更大,所以尽量用整型代替字符串,很多场景是可以通过编码逻辑来实

随机推荐