Mybatis一定要使用commit才能成功修改数据库么?

1.为什么我们有时候不使用commit也能修改数据库成功?

具体完整代码请看(一)Mybatis入门之第一个程序

1.从数据库的层面上来讲,其实这个主要看你用什么“存储引擎”

像以下的代码就是使用了自动提交的mysql引擎。

CREATE TABLE `student` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(20) NOT NULL , 
`age` INT NOT NULL , `score` DOUBLE NOT NULL , PRIMARY KEY (`id`)) ENGINE = MyISAM; 

如果是不支持事务的引擎,如myisam,则是否commit都没有效的。
如果是支持事务的引擎,如innodb,则有系统参数设置是否自动commit,查看参数如下:

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)
mysql>

显示结果为on表示事务自动提交,不用手工去commit,当然,你可以设置其为OFF,然后自己手工去commit。

2.当我们使用myIsam引擎的时候,不使用commit比如下面的代码:
public class StudentDaoImpl implements IStudentDao {
    private SqlSession sqlSession;
	public void insertStu(Student student) {
		try {
			InputStream inputStream;
			inputStream = Resources.getResourceAsStream("mybatis.xml");
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			sqlSession=sqlSessionFactory.openSession();
			sqlSession.insert("insertStudent",student);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

我们可以看到已经更新了一行,我们完全不使用commit


3.当我们使用这个来创建数据表(使用Innodb),然后也不提交,也是使用上面的代码:
CREATE TABLE `student` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(20) NOT NULL , 
`age` INT NOT NULL , `score` DOUBLE NOT NULL , PRIMARY KEY (`id`)) ENGINE = Innodb; 

我们再执行插入时,发现控制台输出是这样的:



好像输入也成功了,但是我去数据库看了一下,居然是空的:



那我们将代码换成这样,加入提交事务:

public class StudentDaoImpl implements IStudentDao {
    private SqlSession sqlSession;
	public void insertStu(Student student) {
		try {
			InputStream inputStream;
			inputStream = Resources.getResourceAsStream("mybatis.xml");
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			sqlSession=sqlSessionFactory.openSession();
			sqlSession.insert("insertStudent",student);
			// 提交事务
			sqlSession.commit();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
		    if(sqlSession!=null){
		        sqlSession.close();
            }
        }
	}
}

执行代码,我们会发现事务提交成功了,同时我们也关闭数据库了:



打开数据库,我们会发现,居然没有id为1的记录,为什么直接跳到2了呢?还记不记得之前插入一次但是没有提交,所以问题就在这里。上一次的提交已经写到事务里面了,只是没有提交,所以这一次提交的时候,上一次默认已经占用了那条记录,只是不写进数据库中。有提交就可以回滚,所以要使用回滚的话,可以使用sqlsession.rollback()



如果我们使用sqlsession.close()的话,我们就不需要使用回滚了。
下面是我把commit去掉,但是留下close的结果,我们可以看到没有commit,但是已经会自动rollback了,所以只要使用sqlsession.close()就会自动回滚再关闭。

此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

技术之路不在一时,山高水长,纵使缓慢,驰而不息。

公众号:秦怀杂货店

### 使用数据库事务在 MyBatisMyBatis 支持两种类型的事务管理器:`JDBC` 和 `MANAGED`[^1]。 #### JDBC 事务管理器 当配置为 `JDBC` 类型时,MyBatis 将会直接使用来自数据源连接对象的提交和回滚设施。这意味着应用程序代码负责显式地调用这些方法来控制事务边界: ```xml <transactionManager type="JDBC"> </transactionManager> ``` 对于 Java 应用程序来说,在执行一系列持久化操作之前开启一个新的事务,并且根据业务逻辑的成功与否决定是否要提交还是回滚该事务是非常重要的。下面是一个简单的例子展示如何通过编程方式处理 JDBC 事务: ```java SqlSession session = sqlSessionFactory.openSession(); try { // 执行一些查询或更新语句... User user = new User(); user.setId(1); user.setName("John Doe"); mapper.insertUser(user); // 提交更改到数据库中 session.commit(); } catch (Exception e) { // 如果发生异常,则撤销所有未保存的数据变更 session.rollback(); throw e; } finally { // 关闭 Session 对象释放资源 session.close(); } ``` #### MANAGED 事务管理器 如果设置成 `MANAGED` 模式的话,那么 MyBatis 不会对任何事物行为做出改变;相反它依赖于容器(比如 Spring Framework 或者 EJB 容器)去管理和协调整个过程中的事务状态变化。这种方式通常用于集成环境之中,其中外部框架已经接管了对事务生命周期的操作权限。 在这种情况下不需要手动编写有关开始/结束事务以及确认/取消修改的相关代码片段,因为这一切都由所使用的特定平台自动完成。 ```xml <transactionManager type="MANAGED"> </transactionManager> ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值