文章目录
- 一、概念
- 1.1、事务
- 1.2、手动提交:autocommit=0
- 1.3、自动提交:autocommit=1
- 二、设置 autocommit 的开启和关闭:
- 2.1、查看当前自动提交状态:
- 2.2、临时设置方法:
- 2.3、永久设置方法:
- 三、spring 底层对自动提交的设置
一、概念
1.1、事务
事务 就是一组的SQL语句,或者说一个独立的工作单元,这一组的SQL语句,要么全部执行成功,要么全部执行失败。
开启事务 : start transaction
或者 begin
提交事务: commit
事务回滚:rollback
1.2、手动提交:autocommit=0
从用户执行 start transaction
(开启事务),到用户执行 commit
命令,这个期间,用户的一系列操作为一个完整的事务周期。
如果不执行 commit
命令,系统则默认事务回滚。
1.3、自动提交:autocommit=1
如果用户在当前情况下(autocommit=1)下执行 start transaction
命令,对数据库进行操作,系统则默认用户对数据库的每一个操作为一个孤立的事务,也就是说用户每进行一次操作系都会 即时提交 或者 即时回滚 。
这种情况下用户的每一个操作都是一个完整的事务周期。
二、设置 autocommit 的开启和关闭:
用户可以将自动提交功能强制置为 OFF 。
这样用户执行SQL语句后将不会被提交了,而执行 commit
命令才提交,执行 rollback
命令回滚。
2.1、查看当前自动提交状态:
mysql> show variables like 'autocommit';
±--------------±------+
| Variable_name | Value |
±--------------±------+
| autocommit | ON |
±--------------±------+
mysql> show global variables like 'autocommit'; ## 全局的
±--------------±------+
| Variable_name | Value |
±--------------±------+
| autocommit | ON |
±--------------±------+
2.2、临时设置方法:
将自动提交功能置为ON ,
set autocommit=1;
将自动提交功能置为OFF ,
set autocommit=0;
2.3、永久设置方法:
通过修改配置文件 my.cnf
文件,通过vim编辑my.cnf文件,在[mysqld](服务器选项下)添加:
autocommit=0
三、spring 底层对自动提交的设置
1)mysql 的 autocommit
配置默认是开启的,也就是每执行一条sql都会提交一次,就算显示的开启事务也会导致多条SQL不在一个事务中,
如果需要相关的SQL在同一个事务中执行,那么必须将 autocommit设置为OFF,再显式开启事务。
2)如果使用spring的事务,那么不存在这个问题,spring的事务默认是关闭自动提交的,做法是判断连接池是否开启事务自动提交,如果连接池开启自动提交则设置自动提交为关闭,否则不做操作,因为某些jdbc驱动做设置自动提交关闭代价昂贵。
org.springframework.jdbc.datasource.DataSourceTransactionManager
/**
* This implementation sets the isolation level but ignores the timeout.
*/
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
//.........
// 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);
}
//.............................
}
spring会将底层连接的自动提交设置为 false。
大部分 java 项目中都会使用到 Spring, 所以即使我们没有对mysql 自动提交做修改,Spring 依然可以保证事务的原子性。