4.数据库事务

本文详细介绍了数据库事务的概念,包括事务的ACID特性,通过案例展示了如何在Java中进行事务控制,如取消自动提交、手动提交和回滚。同时,探讨了事务的四种隔离级别,解释了不可重复读和幻读现象,并提供了查询当前隔离级别的示例代码。最后,讨论了事务隔离级别在解决并发问题中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.事务的概述

多条sql语句作为一个整体出现,要么都执行,要么都不执行
image.pngimage.png

2.事务的具体案例

1.取消DML语言的自动提交
2.有多个更新命令,防止执行一个命令之后关闭连接自动提交,将在命令外手动开关连接

事务的增删改操作通用模板

//    事务的增删改操作通用模板
//    主要是为了防止关闭连接后自动提交
    public void updateTable(Connection conn,String sql,Object...vals){
//        可变形参vals的数量就是占位符的数量
        PreparedStatement ps=null;
        try {
//        2,实例化PreparedStatement对象
            ps=conn.prepareStatement(sql);
//        3.填充占位符
            for(int i=0;i<vals.length;i++){
                ps.setObject(i+1,vals[i]);
            }
//        4.执行
            ps.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //        5.关闭资源
//            conn在方法外打开,也需要在方法外关闭
            JDBCUtils.closeResource(null,ps);
        }
    }

模拟aa给bb转账100元具体操作

public static void main(String[] args) {
        Test1 t=new Test1();
        Connection conn=null;
        try {
            conn=JDBCUtils.getConnection();
//            1.取消数据库的自动提交
            conn.setAutoCommit(false);
//        模拟aa给bb转账100元
            String sql1="update user_table set balance=balance-100 where user=?";
            t.updateTable(conn,sql1,"AA");
//        模拟网络异常
//        System.out.println(10/0);
            String sql2="update user_table set balance=balance+100 where user=?";
            t.updateTable(conn,sql2,"BB");
//            2.数据库手动提交
            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
//            3.出现异常数据库回滚
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally{
//            恢复默认状态
//            针对数据库连接池的使用
            try {
                conn.setAutoCommit(true);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
//            ps在更新命令中已经关闭
            JDBCUtils.closeResource(conn,null);
        }
    }

3.事务属性和四种事务的隔离级别

image.png
image.png
不可重复读:更新字段并提交,其他线程在读取结果会有所不同
例如:网上购买商品刷新界面

image.png
Mysql默认避免不了幻读,默认可以重复读
Oracle默认避免不了不可重复读和幻读,默认读已经提交

4.事务隔离级别具体实现

        Connection conn=JDBCUtils.getConnection();
//        获取当前数据库的隔离级别
//        分别为1,2,4,8,分别对应读未提交,读已提交,可重复读,串行化
        System.out.println(conn.getTransactionIsolation());
//        设置数据库的隔离级别
//        conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

数据库事务查询代码

//    <T>表示这是一个泛型方法,返回类型为T,T类型由实参传入
    public <T> T queryTable(Connection conn,Class<T> clazz,String sql,Object...vals){
        PreparedStatement ps= null;
        ResultSet rs= null;
        try {
//            2.预编译sql语句,占位符赋值
            ps = conn.prepareStatement(sql);
            for(int i=0;i<vals.length;i++){
                ps.setObject(i+1,vals[i]);
            }
//            3.获取结果集
            rs = ps.executeQuery();
            ResultSetMetaData rsmd=rs.getMetaData();
            int columnCount=rsmd.getColumnCount();
//            4,生成返回的结果集对象
            if(rs.next()){
//                通过声明的构造器,new一个T类型的对象
                T t=clazz.getDeclaredConstructor().newInstance();
                for(int i=0;i<columnCount;i++){
                    Object columnVal=rs.getObject(i+1);
                    String columnLabel=rsmd.getColumnLabel(i+1);
//                    反射为对象属性赋值
                    Field field=t.getClass().getDeclaredField(columnLabel);
                    field.setAccessible(true);
                    field.set(t,columnVal);
                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
//            5.关闭资源连接
            JDBCUtils.closeResource(null,ps,rs);
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值