JDBC操作事务

一、事务

要么都成功,要么都失败。

ACID原则

  • 原子性:要么全部完成,要么都不完成。
  • 一致性:总数不变。
  • 隔离性:多个进程互不干扰。
  • 持久性:一旦提交,不可逆,持久化到数据库。

隔离性产生的问题

  • 脏读:一个事务读取了另外一个没有提交的事务。
  • 不可重复读:在一个事务中,重复读取表中数据,并且表中的数据发生了改变。
  • 虚读(幻读):在一个事务中,读取到了别人插入的数据,导致前后读取出来的结果不一致。

创建account表的SQL语句

CREATE TABLE account(
id INT PRIMARY KEY auto_increment,
`name` VARCHAR(40),
money FLOAT
);

INSERT INTO account(id,`name`,money) VALUES(1,'A',1000),
(2,'B',1000),
(3,'C',1000);

模拟转账的代码

package lesson04;

import lesson02.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//模拟转账功能
public class TestTransaction {
    public static void main(String[] args){
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        //conn相当于一个数据库对象
        try {
            conn = JdbcUtils.getConnection();
            //关闭数据库的自动提交功能,会自动开启事务
            conn.setAutoCommit(false);


            String sql1 = "update account set money=money-100 where id=1";
            st = conn.prepareStatement(sql1);
            st.executeUpdate();

            String sql2 = "update account set money=money+100 where id=2";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            //提交事务
            conn.commit();
            System.out.println("成功");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            try {
                //如果失败,则回滚
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }finally {
            //关闭连接
            JdbcUtils.release(conn,st,rs);
        }


    }
}

模拟转账失败的代码。测试原子性。

package lesson04;

import lesson02.JdbcUtils;

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

public class TestTransaction1 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            //连接数据库
            conn = JdbcUtils.getConnection();
            //关闭自动提交功能,相当于自动开启了事务
            conn.setAutoCommit(false);
            //sql语句
            String sql = "update account set money=money-100 where id=1";
            //预编译SQL语句
            st = conn.prepareStatement(sql);
            //执行SQL语句
            st.executeUpdate();
            //故意制造一个错误,让代码自动回滚
            int i = 1/0;
            //sql语句
            String sql1 = "update account set money=money+100 where id=2";
            //预编译SQL语句
            st = conn.prepareStatement(sql1);
            //执行SQL语句
            st.executeUpdate();
            conn.commite();
            System.out.println("执行");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

其中,setAutoCommit(false) 开启事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值