数据库学习之java事务控制

1.事务

数据库**事务( transaction)**是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
比如,我们去银行转账,操作可以分为下面两个环节:
(1)从第一个账户划出款项。 String sql1;
(2)将款项存入第二个账户。 String sql2;
在这个过程中,两个环节是关联的。**第一个账户划出款项必须保证正确的存入第二个账户,如果第二个环节没有完成,整个的过程都应该取消,否则就会发生丢失款项的问题。**整个交易过程,可以看作是一个事物,成功则全部成功,失败则需要全部撤消,这样可以避免当操作的中间环节出现问题时,产生数据不一致的问题。

2.具体Java应用

在一个项目中,要求下列三条语句组成一个事务

String sql = "insert into Train_ticket (user_id,train_id,start_station_name,end_station_name,carriage,seat_grade,seat_location,ride_time,start_time,end_time,price) " +
                "values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"','"+ticket.getStart_station_name()+"','"+ticket.getEnd_station_name()+"',"+ticket.getCarriage()+","+ticket.getSeat_grade()+"," +
                "'"+ticket.getSeat_location()+"','"+ticket.getRide_time()+"','"+ticket.getStart_time()+"','"+ticket.getEnd_time()+"',"+ticket.getPrice()+");";

        String sql2 = "update Train_seat set occupy=0 where train_id='"+ticket.getTrain_id()+"' and carriage="+ticket.getCarriage()+" and seat_location='"+ticket.getSeat_location()+"'";
        String sql3 = "insert into Ride_train values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"',' "+ticket.getRide_time()+"   "+ticket.getStart_time()+"')";

如何确保其原子性:
利用事务的提交和回滚

将组成事务的SQL语句封装到一个方法中要不均成功提交,要不均失败

/***
 * 数据库的事务并发控制
 */
public class Affairs {
    
    

    static Connection conn=null;
    static {
    
    
        conn=DBConnection.getConnection();
    }

    public static int  transaction_control(String sql[]){
    
    

        Statement stmt = null;

        int result = 0;

        try {
    
    

            // 开启事务
            //不把其设置为true之前都是一个当作一个事务来处理
            conn.setAutoCommit(false);

            // 创造SQL语句

            // 执行SQL语句
            stmt = conn.createStatement();
            for (int i = 0; i < sql.length; i++) {
    
    
                stmt.executeUpdate(sql[i]);
            }

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

            System.out.println( "OK!" );
        }
        //发生任何错误均需回滚
        catch (SQLIntegrityConstraintViolationException e3) {
    
    

            result = -1;//主码冲突,返回支付失败
            try {
    
    
                // 回滚事务
                //撤销上面对事务的所有操作哈!
                conn.rollback();
            }  catch (SQLException e2){
    
    

            }

        } catch (Exception e) {
    
    
            e.printStackTrace();
            System.out.println("有错误!");

            try {
    
    
                // 回滚事务
                //撤销上面对事务的所有操作哈!
                conn.rollback();
            }  catch (SQLException e2){
    
    

            }
        }

        return result;

    }

}

工具类DBConnection

//com.mysql.cj.jdbc.Driver数据库驱动
    private static final String DBDRIVER="com.mysql.cj.jdbc.Driver";
    //IP地址202.194.14.120  端口号3306    数据库的名字TrainTicketSystem
    private static final String DBURL="jdbc:mysql://localhost:3306/TrainTicketSystem?&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
    //用户名root
    private static final String DBUSER="root";
    //密码***
    private static final String DBPASSWORD="***";
    static {
    
    
        try {
    
    
            Class.forName(DBDRIVER);
            System.out.println("加载驱动成功");
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
            System.out.println("加载驱动失败");
        }
    }
    public static Connection getConnection() {
    
    
        Connection conn=null;
        try {
    
    
            conn=DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
            System.out.println("连接成功");
        } catch (SQLException e) {
    
    
            // TODO: handle exception
            e.printStackTrace();
            System.out.println("发生连接异常");
        }
        return conn;
    }

3.关键

在执行之前一定要有 conn.setAutoCommit( false );这句话就是设置不自动提交,如果自动提交就是相当于一个sql语句就是一个事务.
如果 conn.setAutoCommit( true )那么就是设置自动提交,第一句能够完成提交,数据库也会有相应的记录,但是第二句如果报错就无法回滚。
总结:事务回滚之前要 conn.setAutoCommit( false );这样吧下面的语句相当于一个事务,一旦出现错误就会撤销所有操作.

猜你喜欢

转载自blog.csdn.net/joey_ro/article/details/108761522