测试代码中,jdbc操作mysql事务回滚失败

32 篇文章 0 订阅
19 篇文章 1 订阅
文章讲述了在MySQL数据库中,由于默认存储引擎MyISAM不支持事务,导致JDBC事务回滚代码无法正常工作。作者通过检查并修改MySQL的默认存储引擎为InnoDB,解决了这个问题。同时,文中提供了一个Java示例,展示了如何在出现异常时回滚事务。
摘要由CSDN通过智能技术生成

首先你要确保你的代码没有问题

问题描述

环境

版本:MySQL 5.7.26

数据库

数据库内容如下所示
在这里插入图片描述
建表语句如下:

-- --------------------------------------------------------
-- 主机:                           127.0.0.1
-- 服务器版本:                        5.7.26-log - MySQL Community Server (GPL)
-- 服务器操作系统:                      Win64
-- HeidiSQL 版本:                  12.4.0.6659
-- --------------------------------------------------------

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;


-- 导出 db1 的数据库结构
CREATE DATABASE IF NOT EXISTS `db1` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */;
USE `db1`;

-- 导出  表 db1.account 结构
CREATE TABLE IF NOT EXISTS `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `money` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- 正在导出表  db1.account 的数据:2 rows
DELETE FROM `account`;
/*!40000 ALTER TABLE `account` DISABLE KEYS */;
INSERT INTO `account` (`id`, `name`, `money`) VALUES
	(1, '张三', 1),
	(2, '李四', 3);
/*!40000 ALTER TABLE `account` ENABLE KEYS */;

/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;

执行事务回滚的java代码

下面是我模拟jdbc事务回滚的代码,由于代码中手动造了一个异常int m = 3/0;,正常来说,sql1会执行成功,ql2会执行失败,由于我们采用了事务管理,因此最终的结果是两个SQL语句都不会执行,数据库内数据不会发生改变

package edu.finance.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

/*
 *JDBC API 详解:DriverManager
 * */
public class JDBCDemo31_Connection {

    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "username ";
        String password = "password ";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql1 = "update account set money = 3000 where id = 1";
        String sql2 = "update account set money = 3000 where id = 2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();




        try {
            // 开启事务
            conn.setAutoCommit(false);
            //5. 执行sql
            int count1 = stmt.executeUpdate(sql1);//受影响的行数
            //6. 处理结果
            System.out.println(count1);
            int m = 3/0;
            //5. 执行sql
            int count2 = stmt.executeUpdate(sql2);//受影响的行数
            //6. 处理结果
            System.out.println(count2);

            // 提交事务
            conn.commit();
            System.out.println("提交事务");
        } catch (Exception throwables) {
            // 回滚事务
            System.out.println("回滚事务");
            conn.rollback();
            throwables.printStackTrace();
        }



        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

原因

查到如下资料

MySQL默认的存储引擎是MyISAM,而MyISAM存储引擎不支持事务处理

  • 使用如下命令,查看你自己的MySQL存储引擎
show variables like '%storage_engine%' 

下图是我已经更改了数据库设置,你的没有修改过,default_storage_engine应该还是MyIsam
在这里插入图片描述

解决

我更改了多个地方,最终是将问题解决了

修改my.ini文件

default-storage-engine=MyIsam改为default-storage-engine=InnoDB改完以后记得重启MySQL
在这里插入图片描述
在这里插入图片描述

如果还是不行

可能是因为你的表已经存在了,即使修改了数据库中的,但是表没有改,
修改你要操作的数据库中的表,我这里是修改account

ALTER TABLE account ENGINE = INNODB;

再次测试,问题解决

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值