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

事务连接池

一、事务概述

(一)事务的定义

事务是数据库提供的一种特性,用于确保数据操作的完整性和一致性。事务将多个数据操作组合成一个逻辑单元,这些操作要么全部成功,要么全部失败。

(二)事务的特性(ACID)

  1. 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败。

  2. 一致性(Consistency):事务执行前后,数据库的状态必须保持一致。

  3. 隔离性(Isolation):多个事务并发执行时,每个事务都好像在独立运行,互不干扰。

  4. 持久性(Durability):事务一旦提交,其对数据库的更改就是永久性的。

二、MySQL中的事务操作

(一)转账的例子

假设冠希给美美转1000元钱,这个操作需要确保以下两个步骤要么全部成功,要么全部失败:

  1. 从冠希的账户中扣除1000元。

  2. 给美美的账户加上1000元。

(二)数据库表结构和初始数据

CREATE TABLE t_account (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(20),money DOUBLE
);INSERT INTO t_account VALUES (NULL, '美美', 10000);
INSERT INTO t_account VALUES (NULL, '冠希', 10000);
INSERT INTO t_account VALUES (NULL, '小凤', 10000);
INSERT INTO t_account VALUES (NULL, '熊大', 10000);
INSERT INTO t_account VALUES (NULL, '熊二', 10000);

(三)使用事务实现转账

在MySQL中,可以通过以下步骤使用事务实现转账操作:

-- 开启事务
START TRANSACTION;-- 从冠希的账户中扣除1000元
UPDATE t_account SET money = money - 1000 WHERE username = '冠希';-- 给美美的账户加上1000元
UPDATE t_account SET money = money + 1000 WHERE username = '美美';-- 提交事务
COMMIT;

如果在执行过程中发生任何错误,可以回滚事务,撤销所有更改:

-- 开启事务
START TRANSACTION;-- 从冠希的账户中扣除1000元
UPDATE t_account SET money = money - 1000 WHERE username = '冠希';-- 给美美的账户加上1000元
UPDATE t_account SET money = money + 1000 WHERE username = '美美';-- 如果发生错误,回滚事务
ROLLBACK;

三、事务的隔离级别

(一)隔离级别概述

事务的隔离级别用于控制事务之间的隔离程度,以解决并发操作中可能出现的问题,如脏读、不可重复读和幻读。

(二)隔离级别分类

  1. Read Uncommitted:最低的隔离级别,允许脏读。

  2. Read Committed:避免脏读,但可能出现不可重复读。

  3. Repeatable Read(默认级别):避免脏读和不可重复读,但可能出现幻读。

  4. Serializable:最高的隔离级别,避免所有并发问题,但性能开销最大。

(三)设置隔离级别

SET SESSION TRANSACTION ISOLATION LEVEL [隔离级别];

四、在JDBC中操作事务

(一)操作事务的方法

在JDBC中,可以通过Connection接口操作事务:

  • void setAutoCommit(boolean autoCommit):设置事务是否自动提交。

  • void commit():提交事务。

  • void rollback():回滚事务。

(二)示例代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TransactionExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "password";try (Connection connection = DriverManager.getConnection(url, user, password)) {// 关闭自动提交模式connection.setAutoCommit(false);// 开启事务String sql1 = "UPDATE t_account SET money = money - 1000 WHERE username = '冠希'";String sql2 = "UPDATE t_account SET money = money + 1000 WHERE username = '美美'";try (PreparedStatement stmt1 = connection.prepareStatement(sql1);PreparedStatement stmt2 = connection.prepareStatement(sql2)) {// 执行事务中的SQL语句stmt1.executeUpdate();stmt2.executeUpdate();// 提交事务connection.commit();} catch (SQLException e) {// 回滚事务connection.rollback();e.printStackTrace();}} catch (SQLException e) {e.printStackTrace();}}
}

五、数据库连接池

(一)连接池概述

数据库连接池是一种资源管理技术,用于高效管理和复用数据库连接。连接池预先创建一定数量的数据库连接,并在需要时将这些连接分配给请求者,使用完毕后归还到池中。

(二)连接池的优势

  1. 节省资源:避免频繁创建和销毁连接的开销。

  2. 提高性能:快速获取和释放连接,提高系统性能。

  3. 资源限制:限制同时打开的连接数量,避免过多的连接消耗过多的系统资源。

(三)常见的连接池

  1. DBCP连接池:Apache开源组织提供的连接池。

  2. C3P0连接池:开源的连接池。

  3. Druid连接池:阿里巴巴提供的连接池,功能强大,性能优越。

(四)Druid连接池的使用

1. 导入Druid的jar包

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version>
</dependency>
2. 编写测试程序

import com.alibaba.druid.pool.DruidDataSource;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class DruidTest {public static void main(String[] args) {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");dataSource.setUsername("root");dataSource.setPassword("password");// 设置连接池参数dataSource.setInitialSize(5);dataSource.setMaxActive(10);dataSource.setMaxWait(2000);dataSource.setMaxIdle(12);dataSource.setMinIdle(3);Connection conn = null;PreparedStatement stmt = null;try {conn = dataSource.getConnection();String sql = "INSERT INTO t_user VALUES (NULL, ?, ?, ?)";stmt = conn.prepareStatement(sql);stmt.setString(1, "eee");stmt.setString(2, "eee");stmt.setString(3, "eee");stmt.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
3. 编写工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JdbcUtils {private static DataSource dataSource;static {Properties props = new Properties();try (InputStream in = JdbcUtils.class.getResourceAsStream("/druid.properties")) {props.load(in);dataSource = DruidDataSourceFactory.createDataSource(props);} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static void close(Connection conn, Statement stmt, ResultSet rs) {try {if (rs != null) rs.close();if (stmt != null) stmt.close();if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}
}
4. 配置文件druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
username=root
password=password
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

六、总结

通过使用事务,可以确保数据操作的完整性和一致性。在MySQL中,可以通过START TRANSACTIONCOMMITROLLBACK命令操作事务。事务的隔离级别可以控制并发操作中的隔离程度,以解决脏读、不可重复读和幻读等问题。

相关文章:

  • Linux笔记---System V共享内存
  • 海市蜃楼的形成原理
  • JVM之内存管理(二)
  • vue 组件函数式调用实战:以身份验证弹窗为例
  • 数字相机的快门结构
  • 互联网大厂Java求职面试:基于RAG的智能问答系统设计与实现-3
  • 4.6java异常处理
  • 每日算法刷题Day2 5.10:leetcode数组1道题3种解法,用时40min
  • Java零组件实现配置热更新
  • C++发起Https连接请求
  • PyQt5基础:QWidget类的全面解析与应用实践
  • 利用多AI协作实现AI编辑器高效开发:创新架构与实践基本构想
  • 【typenum】 1 说明文件(README.md)
  • 【金仓数据库征文】政府项目数据库迁移:从MySQL 5.7到KingbaseES的蜕变之路
  • 数据库故障排查指南大纲
  • Tailwind CSS v4 主题化实践入门(自定义 Theme + 主题模式切换)✨
  • 边缘计算从专家到小白
  • MySQL开篇
  • vscode 中 tasks.json schema
  • 前端面试每日三题 - Day 30
  • 巴防空系统击落印度无人机,印称巴方违反停火协议
  • 中国社科院:网文市场超430亿元,作者破3000万人
  • 成就彼此,照亮世界:“中欧建交50周年论坛”在沪成功举行
  • 名帅大挪移提前开启,意属皇马的阿隆索会是齐达内第二吗
  • 1450亿元!财政部拟发行2025年中央金融机构注资特别国债(二期)
  • 数理+AI+工程,上海交大将开首届“笛卡尔班”招生约20名