java之事务

一.事务的概念

事务是指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。

二.JDBC中使用事务

当JDBC程序向数据库获得一个Connection对象时,默认这个Connection对象会自动向数据库提交发送的SQL语句,如果想要关闭这种默认的提交方式,让多条SQL在一个事务中执行,可以使用如下的语句控制:

Connection.setAutoCommit(false);//开启事务
Connection.rollback();//回滚事务
Connection.commit();//提交事务

2.1示例

下面模拟银行转账的业务,用户A转账给用户B,用户B接收用户A的转账。

update account set money=money-10000 where name='A';
update account set money=money+10000 where name='B';

 

package com.boxiaoyuan.www;

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

import org.junit.Test;



public class Demo02 {
    /**
     * 模拟转账成功的场景
     */
    @Test
    public void transantion1() {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            conn.setAutoCommit(false);//通知数据库开启事务
            String sql = "update account set money=money-10000 where name='A'";
            stmt = conn.prepareStatement(sql);
            stmt.executeUpdate();
            String sql2 = "update account set money=money+10000 where name='B'";
            stmt = conn.prepareStatement(sql2);
            stmt.executeUpdate();
            conn.commit();//执行完上面两条语句后,提交事务
            System.out.println("执行成功");
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
    /**
     * 模拟转账过程中出现异常,程序自动回滚
     */
    @Test
    public void testTransaction2() {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            conn.setAutoCommit(false);//告诉数据库开始事务
            String sql = "update account set money=money-10000 where name='A'";
            stmt = conn.prepareStatement(sql);
            stmt.executeUpdate();
            int m = 2/0;//程序出错,导致后续的程序无法进行,事务无法正常提交,数据库自动回滚
            String sql2 = "update account set money=money+10000 where name='B'";
            stmt = conn.prepareStatement(sql2);
            stmt.executeUpdate();
            conn.commit();//提交事务
            System.out.println("执行成功");
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
    /**
     * 模拟转账过程中出现异常,手动回滚事务
     */
    @Test
    public void testTransaction3() {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            conn.setAutoCommit(false);//告诉数据库开始事务
            String sql = "update account set money=money-10000 where name='A'";
            stmt = conn.prepareStatement(sql);
            stmt.executeUpdate();
            int m = 2/0;//程序出错
            String sql2 = "update account set money=money+10000 where name='B'";
            stmt = conn.prepareStatement(sql2);
            stmt.executeUpdate();
            conn.commit();//提交事务
            System.out.println("执行成功");
        } catch (SQLException e) {
            try {
                conn.rollback();//捕获异常后手动执行数据库回滚操作
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}

 

上一篇:Java,PL/SQL调用 ORACLE存储函数以及存储过程


下一篇:mysql 5.7.20 取得动态sql执行结果