1 MySQL的autocommit設置
MySQL默認是開啟自動提交的,即每一條DML(增刪改)語句都會被作為一個單獨的事務進行隱式提交。如果修改為關閉狀態,則執行DML語句之后要手動提交 才能生效。
查詢當前會話的自動提交是否開啟:
1
2
3
4
5
6
|
mysql> show variables like 'autocommit' ; + ---------------+-------+ | Variable_name | Value | + ---------------+-------+ | autocommit | ON | + ---------------+-------+ |
查詢全局的自動提交是否開啟:
1
2
3
4
5
6
|
mysql> show global variables like 'autocommit' ; + ---------------+-------+ | Variable_name | Value | + ---------------+-------+ | autocommit | ON | + ---------------+-------+ |
通過修改autocommit變量可以關閉和開啟操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
關閉當前會話的自動提交模式 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的值。
1
2
3
|
[mysqld] ... autocommit=0 |
Spring中對自動提交的控制
MySQL的JDBC驅動包 mysql-connector-java 會給會話的connection默認開啟自動提交,譬如 mysql-connector-java-8.0.22版本的代碼:
1
2
|
//com.mysql.cj.protocol.a.NativeServerSession.java private boolean autoCommit = true ; |
常用的數據庫連接池 如HikariCP,druid等,默認也是開啟自動提交,會將connection的自動提交設置都改為true。
druid在初始化DataSource的時候設置connection的autocommit為true。代碼如下:
1
2
3
4
5
6
7
8
9
10
11
|
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:
1
2
3
4
5
6
|
com.zaxxer.hikari.HikariConfig.java public HikariConfig() { ... isAutoCommit = true ; } |
對于事務管理器PlatformTransactionManager管理的顯式事務(譬如@Transactional注解聲明)在 開啟事務時會關閉自動提交模式。 代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@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)的資料請關注服務器之家其它相關文章!
原文鏈接:https://juejin.cn/post/6916415803852062734