0
点赞
收藏
分享

微信扫一扫

MySQL中的事务

一脸伟人痣 2022-04-13 阅读 80
mysql

目录

事务(Transaction)

事务的四大特性

Atomic-----原子性

Consistency-----一致性

Isolation-----隔离性

Durably-----持久性

MySQL中使用事务

 例子

JDBC中使用事务

例子


事务(Transaction)

一个最小的不可再分的工作单元,最终表达为一条或者多条SQL语句,对应一个完整的业务,比如:借书,转账等

事务的四大特性

业务动作对应的SQL会被看成一个整体,是不可再分的。事务中操作的执行过程只会有两种情况,成功/失败,当事务中所有操作都执行成功(commit)时,事务成功。当其中任意一个操作失误时,其他已经被执行的操作会撤销然后回滚(rollback),事务失败。

一致性指的是数据一致性,事务必须使数据库从一个一致性状态变换到另外一个一致性状态

一个事务的执行不能被其他事务干扰。针对多用户场景,当有多个用户同时针对数据进行增删查改时,需要保持隔离的特性。理想情况下,一个用户在对数据进行修改时,不能有其他用户对该用户的操作存在干扰

持久性也称永久性,当事务成功提交时,数据库中数据的修改就是永久性的

MySQL中使用事务

-- 事务开始
start transaction;
-- 执行的SQL语句
insert语句/update语句/delete语句
-- 提交
commit;

 例子

  • 先建表
-- 书籍信息表
CREATE TABLE `library`.`books` (
  `bid` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL COMMENT '书籍名称',
  `count` INT NOT NULL COMMENT '存量',
  `total` INT NOT NULL COMMENT '总量',
  PRIMARY KEY (`bid`))
COMMENT = '书籍信息';

-- 借阅者信息表
CREATE TABLE `library`.`readers` (
  `rid` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`rid`))
COMMENT = '借阅者信息';

-- 借阅记录表
CREATE TABLE `library`.`records` (
  `reid` INT NOT NULL AUTO_INCREMENT,
  `rid` INT NOT NULL COMMENT '谁借的',
  `bid` INT NOT NULL COMMENT '借的哪本书',
  `borrowed_at` DATETIME NOT NULL DEFAULT current_timestamp COMMENT '借阅时间',
  PRIMARY KEY (`reid`))
COMMENT = '借阅记录';
  •  插入书籍信息和借阅人信息
-- 插入书籍
insert into books(name,count,total) values 
   ('三国演义',30,30),
   ('鲁滨逊漂流记',10,10);

-- 插入借阅者信息
insert into readers(name) values 
   ('张三'),
   ('李四');

 

  •  借书操作
  •  必须要进行commit,事务才算提交成功,否则会回滚
-- 借阅人:借书 rid为1的张三借阅了bid为2的鲁滨逊漂流记
start transaction;
update books set count = count - 1 where bid = 2;
insert into records (rid,bid) values (1,2);
commit;

 

JDBC中使用事务

例子

  • 先连接数据库
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author happy
 */

public class DBUtil {
    private static final DataSource dataSource;
    
    static {
        MysqlDataSource db = new MysqlDataSource();
        String url = "jdbc:mysql://localhost:3306/library?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";
        db.setUrl(url);
        db.setUser("root");
        db.setPassword("12345");
        
        dataSource = db;
    }
    
    public static Connection connection() throws SQLException {
        
        return dataSource.getConnection();
    }
}
  •  rid为2李四借阅bid为1的三国演义
import com.zhang.util.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author happy
 * 有事务,并且commit
 */
public class Demo1 {
    public static void main(String[] args) throws SQLException {
        String sql1 = "update books set count = count -1 where bid = 1";
        String sql2 = "insert into records (rid,bid) values (2,1)";
        // 要在同一个事务中,操作 sql1 和 sql2,意味着必须在一条 Connection 完成
        // 关闭connection的自动提交,需要手动提交
        try(Connection c = DBUtil.connection()){
            // 关闭自动提交
            c.setAutoCommit(false);
            try(PreparedStatement ps = c.prepareStatement(sql1)){
                ps.executeUpdate();
            }
            try(PreparedStatement ps = c.prepareStatement(sql2)){
                ps.executeUpdate();
            }
            c.commit();
        }
        System.out.println("借阅成功");
    }
}

举报

相关推荐

0 条评论