当前位置: 首页 > java >正文

MySQL事务和JDBC中的事务操作

一、什么是事务

事务是数据库操作的最小逻辑单元,具有"全有或全无"的特性。以银行转账为例:

典型场景

  • 从A账户扣除1000元

  • 向B账户增加1000元
    这两个操作必须作为一个整体执行,要么全部成功,要么全部失败

MySQL的事务特性

  • 默认自动提交模式(每条SQL作为独立事务)

  • 通过START TRANSACTION显式开启事务

  • 使用COMMIT提交或ROLLBACK回滚

 二、使用事务

MySql数据库中使用事务,提供了两种方式(重点)

1、使用命令的方式

-- 开启事务
START TRANSACTION;
update t_account set money=money-1000 where username='冠希';
update t_account set money=money+1000 where username='美美';
-- 提供事务(事务已经结束了,数据永久的保存到数据库中了)
COMMIT;
-- 回滚事务(事务已经结束了,数据回滚到最初始化的状态)
ROLLBACK;

2、使用不默认提交的方式

show VARIABLES like '%commit%';-- 查看事务是否默认提交
set autocommit =off;-- 设置不默认提交
update t_account set money=money-1000 where username='冠希';
update t_account set money=money+1000 where username='美美';
COMMIT;-- 或者rollback

当会话结束此次关闭不默认提交的的事务就结束,新的会话还是默认提交事务。

3、JDBC中操作事务

JDBC事务验证实例:

package com.qcby.dao;import com.qcby.utils.JdbcUtils2;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcUpdate {public static void main(String[] args) {Connection connection =null;Statement statement=null;//增删改不需要结果集//ResultSet resultSet=null;try {//jdbc连接数据库//1.加载驱动//2.获取连接(URL 用户名  密码)connection = JdbcUtils2.getConnection();//开启事务(关闭自动提交)connection.setAutoCommit(false);//3.编写sqlString sql1="UPDATE account SET money = money + 1000 WHERE name = 'ccc'";String sql2="UPDATE account SET money = money - 1000 WHERE name = 'bbb'";//4.获取执行sql的stmt的对象statement = connection.createStatement();//返回的结果条数int i=statement.executeUpdate(sql1);//int m=10/0;int i2=statement.executeUpdate(sql2);//注意提交事务connection.commit();System.out.println("转账成功!");} catch (SQLException e) {//回滚事务(如果发生异常)try {if (connection != null) {connection.rollback();System.out.println("转账失败,已回滚!");}} catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();}finally {//7.关闭资源(先开的后关 后开的先关)JdbcUtils2.close(connection, statement);}}
}

事务的特性:

  • 原子性(Atomicity):要么全做,要么全不做
  • 一致性(Consistency):钱的总数不变(你-100,商家+100)
  • 隔离性(Isolation):你和别人同时买东西不会互相干扰
  • 持久性(Durability):一旦成功,数据永久保存

不考虑隔离性将引发的问题:

脏读:读到另一个事务未提交的数据。

不可重复读“变魔术的字”看商品的价格突然变了,别人改的时候提交了,你这也改了。

幻读:“凭空出现的行“就像你数教室里的人数,数到一半又进来几个学生

 

设置事务的隔离级别(解决读的问题) 

 1.事务的隔离级别(设置数据库的隔离级别,根据级别的不同,解决上述的读的问题) * Read uncommitted‐‐ 什么都解决不了

* Read committed‐‐ 避免脏读,但是不可重复读和虚读有可能产生

* Repeatable read‐‐ 避免脏读和不可重复读,虚度有可能产生的

* Serializable‐‐ 避免各种读

2.4种隔离级别有安全性和效率

* 安全 Serializable > Repeatable read > Read committed > Read uncommitted

* 效率 Serializable < Repeatable read < Read committed < Read uncommitted

3.数据库都有自己默认的隔离级别

* MySQL的数据库,默认的隔离级别是Repeatable read,避免脏读和不可重复读。

演示脏数据(别人事务还未提交你就看到了)

在mysqlbin目录下开启两个窗口,一个A窗口(左),一个B窗口(右)。

A: 

B:

A: 

B:

 避免脏读和演示不可重复读

A:

B:

 

A:

B:

A:中再查询一次

两次查询结果不同,发生不可重复读

避免不可重复读 

两个窗口同时设置隔离级别为REPEATABLE READ

 A:

B:

A:

 与第一次查询结果相同,避免了不可重复读

B: 

A:

避免各种读

 A:

B:

 没有提交事务

A:

SERIALIZABLE 是最严格的隔离级别

  • 它会在读取数据时自动加共享锁
  • 其他事务不能修改这些数据,直到事务结束
  • 如果其他事务正在修改这些数据,查询会被阻塞

 当B提交或回滚时,事务结束,A就可以查询出结果。

http://www.xdnf.cn/news/5178.html

相关文章:

  • 深入解析:如何基于开源p-net快速开发Profinet从站服务
  • 2025年“深圳杯”数学建模挑战赛C题国奖大佬万字思路助攻
  • Java虚拟机的基本结构
  • Web3 初学者学习路线图
  • 各种音频产品及场景总结
  • 5.Redission
  • golang-ErrGroup用法以及源码解读笔记
  • 单因子实验 方差分析
  • Spring MVC 视图解析器 (ViewResolver) 如何配置? Spring Boot 是如何自动配置常见视图解析器的?
  • 基于人工智能的个性化 MySQL 学习路径推荐研究
  • PHP框架在分布式系统中的应用!
  • 通过user-agent来源判断阻止爬虫访问网站,并防止生成[ error ] NULL日志
  • Python 面向对象编程
  • 【常用算法:排序篇】3.极速排序秘籍:快排三大优化与高效选择算法
  • 嵌入式学习--江协51单片机day4
  • 华为云服务器核心用途全景解析:从基础服务到行业革新​​
  • AIGC时代大模型幻觉问题深度治理:技术体系、工程实践与未来演进
  • (九)什么是传输线模型? 进入传输线模型的条件? why讯号反射(reflection)? 各种阻抗匹配方式与差异?
  • 递归函数(斐波那契数列0,1,1,2,3,5,8,13,21,34,55...)
  • AWS SNS:解锁高并发消息通知与系统集成的云端利器
  • 【Linux】基础 IO(一)
  • Satori:元动作 + 内建搜索机制,实现超级推理能力
  • Proser:在使用中改进
  • 使用FastAPI和React以及MongoDB构建全栈Web应用02 前言
  • 什么是向量数据库?向量数据库和关系数据库有什么区别?
  • Java常用类概述
  • C语言_函数hook_LD_PRELOAD原理和示例
  • 阿里云购买ECS 安装redis mysql nginx jdk 部署jar 部署web
  • Docker磁盘空间不足问题
  • 【算法-哈希表】常见算法题的哈希表套路拆解