Examples of JDBC Transactions

 

The previous article included some theoretical knowledge about JDBC transaction management. Here is an example (mainly afraid that an essay will be too long to install everything and then separate it)

 

Generally speaking, when it comes to business management, it is all about transferring money as an example. Well, yes, we do too.

 

This is the t_account table in the database, which is loaded with the amount~ It can be understood as a bank account, with id, user name, and user's deposit.

 

Then a simple Java entity class:

package com.java.ws.transactionDemo;

/**
 * The entity corresponding class of the database
 * Bank account class
 * @author 85060
 *
 */
public class Account {
    private int id;
    private String accountName;
    private float accountBalance;
    
    public Account(int id, String accountName, float accountBalance) {
        this.id = id;
        this.accountBalance = accountBalance;
        this.accountName = accountName;
    }
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getAccountName() {
        return accountName;
    }
    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }
    public float getAccountBalance() {
        return accountBalance;
    }
    public void setAccountBalance(float accountBalance) {
        this.accountBalance = accountBalance;
    }
    
    
}

 

DbUtil class: It is a class that encapsulates the JDBC driver and connection code. It will not be posted. It mainly provides Connection, closes database connection and preprocessing.

 

Then look at this AccountInOutDao, we are not very standardized here, and the logic code is also written here:

package com.java.ws.transactionDemo;

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

import com.java.ws.util.DbUtil;

public class AccountInOutDao {
    
    private static DbUtil dbUtil = new DbUtil();
    
    /* new Account(1, "Zhang San", 500);
     new Account(2, "Li Si", 1000); */
    
    
    public static int outMoney(Account user, int amount, Connection con) {
        
        String sql = "UPDATE t_account set accountBalance = accountBalance - ? where id = ?";
        PreparedStatement pstmt = null;
        int result = 0;
        try {
            
            
            
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, amount);
            pstmt.setInt(2, user.getId());
            result = pstmt.executeUpdate(); // return the number of executions
            
            
            
        } catch (SQLException e) {
             // TODO Auto-generated catch block 
            System.out.println("An error occurred in the database operation of borrowing money" );
            e.printStackTrace ();
        } finally {
            dbUtil.close(pstmt, con);
        }
        
        return result;
    }
    
    
    public static int inMoney(Account user, int amount, Connection con) {
        
        String sql = "UPDATE t_account set accountBalance = accountBalance + ? where id = ?";
        PreparedStatement pstmt = null;
        int result = 0;
        try {
            
            
            
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, amount);
            pstmt.setInt(2, user.getId());
            result = pstmt.executeUpdate(); // return the number of executions
            
            
            
        } catch (SQLException e) {
             // TODO Auto-generated catch block 
            System.out.println("An error occurred in the database operation of borrowing money" );
            e.printStackTrace ();
        } finally {
            dbUtil.close(pstmt, con);
        }
        
        
        return result;
    }
    
    
    public static void main(String[] args) {
     Connection con = dbUtil.getCon();
        System.out.println( "Zhang San wants to transfer 200 yuan" );
         if (outMoney( new Account(1, "Zhang San", 500), 200, con) != 0 ) {
            System.out.println( "Successfully transferred money" );
        }
        
        
        System.out.println( "Zhang San wants to transfer 200 yuan" );
         if (inMoney( new Account(2, "Li Si", 1000), 200, con) != 0 ) {
            System.out.println( "Successfully received money" );
        }
        
    }
    
    
}

Result after operation:

 

 

Here is an ordinary and normal operation situation. It depends on whether the money is successful and the money is also successful. But what if we now artificially create an anomaly between transferring and receiving money?

public static void main(String[] args) {
        
        System.out.println( "Zhang San wants to transfer 200 yuan" );
         if (outMoney( new Account(1, "Zhang San", 500), 200) != 0 ) {
            System.out.println( "Successfully transferred money" );
        }
        
        System.out.println( 1/0 ); //created an exception
        
        System.out.println( "Zhang San wants to transfer 200 yuan" );
         if (inMoney( new Account(2, "Li Si", 1000), 200) != 0 ) {
            System.out.println( "Successfully received money" );
        }
        
}

The result is, obviously:

 

 

 

 

Zhang San transferred 200 yuan, but Li Si received nothing. If this is in the real banking system, hhh.

 

So we use transaction management here, give a try catch block, and roll back if an error is caught.

    public static void main(String[] args) {
        
        Connection con = null;
        
        try {
            
            
            
            
            con = dbUtil.getCon();
            con.setAutoCommit(false);
            
            
            System.out.println( "Zhang San wants to transfer 200 yuan" );
             if (outMoney( new Account(1, "Zhang San", 500), 200, con) != 0 ) {
                System.out.println( "Successfully transferred money" );
            }
            
            System.out.println( 1/0);   // Create exception 
            
            System.out.println( "Zhang San wants to transfer 200 yuan" );
             if (inMoney( new Account(2, "Li Si", 1000), 200, con) != 0 ) {
                System.out.println( "Successfully received money" );
            }
            
            
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println( "Transfer failed!" );
             try {
                
                
                con.rollback(); // There is an error, rollback 
                System.out.println("Just walked the rollback step" );
                
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
        } finally {
            try {
                
                
                con.commit();   // Final submission, if there is no exception, submit it normally, if there is an exception, submit and roll back those operations in front of that position
            
            
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            dbUtil.close(con);
        }
        
        
        
  }
    

 

result:

 

The database information has not changed:

 

 

Just now we adopted all rollbacks, or fixed-point rollbacks:

 

Savepoint savePoint = null;

savePoint = con.setSavepoint(); // memory point

                  
con.rollback(savePoint); // There is an error, roll back to the memory point

 

 

Attached:

At the beginning, I established Connections in InMoney and OutMoney respectively, and then created a Connection in the main method to roll back, thinking that it should be possible to roll back to the initial situation of the main con. The result is not good, it has to be changed to a Connection. In the following Baidu related information, I saw that when multiple threads use a Connection, it will cause transaction confusion. . I think this is why there is a connection pooling technology.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324461671&siteId=291194637