【数据库编程】5.事务

1. 基本介绍

  1. JDBC程序中当一个Connection对象创建时,默认情况下时自动提交事务。每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
  2. JDBC中为了让多个SQL作为一个整体执行,需要使用事务。
  3. 调用Connection的setAutoCommit(false)可以取消自动提交事务,调用该方法后也就默认开启了事务。
  4. 在所有的SQL语句都成功执行后,调用Connection的commit()方法提交事务。
  5. 在其中某个操作失败或出现异常时,调用Connection的rollback()方法回滚事务。

2. 转账案例

创建一个账户表并插入两条数据,用于演示转账。

CREATE TABLE `account` (
	`id` INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(32) NOT NULL DEFAULT '',
	`balance` DOUBLE NOT NULL DEFAULT 0
) CHARACTER SET = utf8;

INSERT INTO `account`
VALUES (1, 'alan', 20000),
	(2, 'mike', 10000);

让id为1的用户账户-100,id为2的用户id+100。代码如下:

@Test
public void testTransaction() throws IOException, ClassNotFoundException {
    // 获取值
    Properties properties = new Properties();
    properties.load(new FileInputStream("src\\mysql.properties"));
    String user = properties.getProperty("user");
    String password = properties.getProperty("password");
    String dirver = properties.getProperty("dirver");
    String url = properties.getProperty("url");
    // 注册驱动
    Class.forName(dirver);
    // 得到连接和Statement
    Connection connection = null;
    PreparedStatement ps1 = null;
    PreparedStatement ps2 = null;
    String sql1 = "update account set balance = balance - 100 where id = 1";
    String sql2 = "update account set balance = balance + 100 where id = 2";

    try {
        connection = DriverManager.getConnection(url, user, password);
        // 关闭自动提交事务
        connection.setAutoCommit(false);
        // 执行第一条语句
        ps1 = connection.prepareStatement(sql1);
        ps1.executeUpdate();
        // 模拟一条语句执行结束后发生异常
        int a = 1 / 0;
        // 执行第二条语句
        ps2 = connection.prepareStatement(sql2);
        ps2.executeUpdate();
        // 提交事务
        connection.commit();
    } catch (Exception e) {
        try {
            // 回滚事务
            connection.rollback();
            throw new RuntimeException(e);
        } catch (SQLException e1) {
            throw new RuntimeException(e1);
        }
    } finally {
        try {
            if (ps1 != null) {
                ps1.close();
            }
            if (ps2 != null) {
                ps2.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

执行第一条语句之后发生异常,第二条语句不会执行,但使用了事务回滚,数据表中数据保持不变。如图:

image-20210811110402769

posted @   爵岚  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示