数据库事务提交的三种方式:

手动显式提交、隐式提交及自动提交。

参考:https://blog.csdn.net/qq_43686584/article/details/84548264

  • 手动显式提交:

    手动管理事务时,需要用COMMIT命令直接完成的提交为显式提交。相关sql为:

    SQL>COMMIT;
    
  • 自动提交

    自动提交开启了之后相当于每次sql都是一个事务,并自动提交它,如果sql语句执行失败会自动还原现场。相关sql为:

	 SQL>SET AUTOCOMMIT ON;
  • 隐式提交
    不管是手动管理事务还是自动管理事务,都存在隐式自动提交。
    隐式提交的场景:
    1、正常执行完DDL语句。
    2、正常执行完DCL语句。
    3、正常退出数据库管理软件或切换用户时没有明确发出commit或者rollback。

    对应的SQL命令有:用SQL命令间接完成的提交为隐式提交,ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。举例说明:

    以scott账号登陆,执行delete from dept where deptno=50后,再换system账号登陆,发现deptno=50的数据行已经被删除了,而show autocommit=OFF;
    
    原因:同一客户端切换用户,使用disconnect、connect命令,是会隐式提交事务的。
    
    解决方法:再打开一个控制台sqlplus用另一用户登录啊。在一个sqlplus不可能用多个session的。
    
    
    
为什么需要隐式提交:
  • 我们在执行DDL语句的时候,Oracle需要在它的系统表中进行元数据的记录操作(即:除了建表还会进行不少insert操作)DML会对每个语句的每条记录都做日志记录以便于回滚,而DDL往往没必要搞这么复杂,从功能和易用性上看隐式提交都是最好的选择。
通过不同的数据库来介绍自动提交和手动提交:

mysql数据库原始操作默认是自动提交,具体由框架和中间件封装后的数据库操作是不是自动提交要看具体框架。

Oracle数据库原始操作默认是手动管理事务。所有自动提交,都是一些别的框架或中间件提供的.

我们还可以把数据库的客户端图形化操作工具sqlyang、dbeaver、Plsql Dev看作是数据库中间件,他们是自动还是手动提交,取决于自己这个软件。比如

sqlyang操作mysql数据库时,是默认自动管理事务(即自动提交的),即你的操作会自动提交   

Dbeaver操作oracle数据库时,是默认自动管理事务的(即自动提交的 ),即你的操作会自动提交。    

PLSQL Dev 操作oracle数据库时,是默认手动管理事务(即非自动提交的),即你的操作需要手动提交或回滚。 
举例:

SX银行某XD系统的本地eclipse开发所连接的Oracle库是需要手动管理事务的,而测试和生产上的oracle数据库却是自动提交的。

这是因为,某银行的web项目测试环境和生产环境都是部署在他们的weblogic服务器上,根据银行的规范,部署在WebLogic Server上的应用程序如果需要访问数据库,原则上需要通过WebLogic提供的JDBC连接池来管理数据库连接。而WebLogic 提供的JDBC连接池的connction上的事务是自动提交的。(这里weblogic不仅作为web服务器,还作为数据库中间件而存在了)

那么,如果业务场景需要你手动管理事务呢?那就java代码里写下手动管理事务呗。如下

package com.amar.dateAndCalendar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import com.amar.utils.JDBCUtils;

public class LL {
	public static Logger log=Logger.getLogger(LL.class);
	public static void main(String[] args) throws IOException, SQLException {
        
		Connection conn=JDBCUtils.getConnection();
		boolean autoCommit = conn.getAutoCommit();
		log.info("此环境是否自动提交呢"+autoCommit);
		if (autoCommit) {
			conn.setAutoCommit(false);
		}
		try {
			//DML语句一
			//DML语句二
			//DML语句三
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			log.info(e.getMessage(),e);
			throw e;
		}finally {
			conn.setAutoCommit(autoCommit);//手动管理事务用完以后恢复回原来。
		}
	}
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐