首先你要确保你的代码没有问题
问题描述
环境
版本: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;