20【JDBC的事务处理】


上一篇19【CallableStatement 接口】


下一篇21【JDBC操作数据库元数据】

目录【MySQL零基础系列教程】



20【JDBC的事务处理】

1.1 JDBC的事务处理

之前我们是使用MySQL的命令来操作事务。接下来我们使用JDBC来操作银行转账的事务。

  • 数据准备:
CREATE TABLE account (  
    id INT PRIMARY KEY AUTO_INCREMENT,  
    name VARCHAR(10),  
    money double  
);  
-- 添加数据  
INSERT INTO account (name, money) VALUES ('a', 1000), ('b', 1000);

select * from account;

1.1.1 事务相关API

  • Connection中事务相关方法如下:
方法名描述
boolean getAutoCommit()获取本次连接是否自动提交事务,默认true
void setAutoCommit(boolean autoCommit)设置本次连接是否自动提交事务
void commit()提交事务
void rollback()回滚事务
int getTransactionIsolation()获取事务的隔离级别
void setTransactionIsolation(int level)设置事务的隔离级别
Savepoint setSavepoint()设置事务保存点
void rollback(Savepoint savepoint)回滚到保存点

1.1.2 案例测试

1)模拟转账业务
  • 示例代码:
package com.dfbz.demo;

import com.dfbz.utils.JdbcUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo15_事务 {

    /**
     * 模拟事务
     * @throws Exception
     */
    @Test
    public void test1() throws Exception{
        //创建连接对象
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JdbcUtils.getConnection();

            // 设置事务不要自动提交(手动提交,默认情况下,事务是自动提交的)
            conn.setAutoCommit(false);

            //创建语句对象
            stmt = conn.createStatement();

            //a扣钱
            stmt.executeUpdate("update account set money=money-500 where name='a'");

            // 模拟异常
//            System.out.println(100 / 0);

            // b加钱
            stmt.executeUpdate("update account set money=money+500 where name='b'");

            // 提交事务
            conn.commit();

            System.out.println("转账成功");
        } catch (Exception e) {

            try {
                // 回滚事务
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }

            System.out.println("转账失败");
        } finally {
            JdbcUtils.close(conn, stmt);
        }
    }
}
2)事务隔离级别

Connection中有如下静态常量来规定隔离级别:

  • TRANSACTION_READ_UNCOMMITTED(1):读未提交
  • TRANSACTION_READ_COMMITTED(2):读已提交
  • TRANSACTION_REPEATABLE_READ(4):可重复读
  • TRANSACTION_SERIALIZABLE(8):串行化

测试代码:

/**
 * 测试隔离级别
 *
 * @throws Exception
 */
@Test
public void test2() throws Exception {
    Connection conn = JdbcUtils.getConnection();

    //创建语句对象
    Statement stmt = conn.createStatement();

        /*
            TRANSACTION_READ_UNCOMMITTED(1): 读未提交
            TRANSACTION_READ_COMMITTED(2): 读已提交
            TRANSACTION_REPEATABLE_READ(4): 可重复读
            TRANSACTION_SERIALIZABLE(8): 串行化
         */

    // 将本次连接的隔离级别设置为读未提交
    conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

    /*
     先在其他窗口创建一个事务修改数据但不提交,
     然后再断点执行下面代码,
     看下是否能查询到其他事务没提交的数据
     */
    ResultSet rs = stmt.executeQuery("select * from account");

    while (rs.next()) {

        String name = rs.getString("name");
        double money = rs.getDouble("money");

        System.out.println("name: " + name);
        System.out.println("money: " + money);
    }

    JdbcUtils.close(conn, stmt);
}
3)事务回滚点
  • 测试代码:
/**
 * 测试回滚点
 *
 * @throws Exception
 */
@Test
public void test3() throws Exception {
    Connection conn = JdbcUtils.getConnection();

    // 设置手动提交事务
    conn.setAutoCommit(false);

    //创建语句对象
    Statement stmt = conn.createStatement();

    stmt.executeUpdate("update account set money=900;");

    // 设置保存点
    Savepoint p1 = conn.setSavepoint();

    stmt.executeUpdate("update account set money=800;");

    // 设置保存点
    Savepoint p2 = conn.setSavepoint();

    stmt.executeUpdate("update account set money=700;");

    // 回滚到p1保存点
    conn.rollback(p1);

    // 提交事务
    conn.commit();

    JdbcUtils.close(conn, stmt);
}

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

緑水長流*z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值