數據庫開發四:JDBC數據庫開發進階一(事務處理)

文章相關視頻出處:https://developer.aliyun.com/lesson_1698_13612#_13612

一、事務四大屬性(ACID)

分別是原子性、一致性、隔離性、持久性.
1、原子性(Atomicity):事務中所有的操作是不再分割的原子單位.事務中的所有操作要麼全部執行成功,要麼全部執行失敗.
2、一致性(Consistency):事務執行後,數據庫狀態與其他業務規則保持一致.如轉賬,無論事務執行成功與否,參與轉賬的2個賬號餘額之和應該是不變的
3、隔離性(Isolation):在併發操作中,不同事物之間應該隔離開來,使每個併發中的事務不會相互干擾
4、持久性(Durability):一旦事務提交成功,事務中所有的數據操作必須被持久化到數據庫中,即使提交事務後,數據庫馬上崩潰,在數據庫重啓時,也必須能保證通過某種機制恢復數據

jdbc事務
在jdbc中處理事務,都是通過Connection完成的,同一事務中的所有操作,都在使用同一個Connection對象
1jdbc中的事務
Connection的三個方法與事務相關;
setAutoCommit(boolean);設置是否爲自動提交事務,執行一條語句就提交,設置爲false才能合理使用事務,因爲操作往往是多個操作綁定在一起.
commit();提交結束事務
rollback();回滾結束事務
jdbc處理是事務的代碼格式:
try{
    con.setAutoCommit(false);//開啓事務
    con.commit();提交事務
}catch(){
    con.rollback();回滾事務
}

二、代碼

數據庫

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `balance` decimal(12,0) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

 

package jdbc;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * jdbc完成事務處理
 * Created by kevin on 2020/3/25.
 */
public class Demo4 {
    public void zhuanzhang(String from,String to,double money){
        Connection connection = null;
        try {
            //Connection 同一事務中的所有操作,都在使用同一個Connection對象
            connection = JdbcUtils.getConnection();
            //開啓事務
            connection.setAutoCommit(false);
            AccountDao accountDao = new AccountDao();
            accountDao.updateBalance(connection,from,-10000);
            if(true){
                throw new RuntimeException("失敗了");
            }
            accountDao.updateBalance(connection,to,+10000);
            //提交事務
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                //回滾事務
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Test
    public void fun1(){
        zhuanzhang("ls","zs",10000);
    }
}

 當拋出失敗了的異常時,2個用戶數據未出現變更和數據錯亂,體現了事務的作用

package jdbc;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/**
 * Created by kevin on 2020/3/24.
 */
public class JdbcUtils {
    private static Properties properties = null;
    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbconfig.properties");
            properties = new Properties();
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection() throws Exception{

        Class.forName(properties.getProperty("driverClassName"));
        return DriverManager.getConnection(properties.getProperty("url"),properties.getProperty("name"),properties.getProperty("password"));
    }


}

 

package jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
/**
 * Created by kevin on 2020/3/25.
 */
public class AccountDao {

    /**
     * 修改指定用戶的餘額
     * @param connection
     * @param name
     * @param balance
     */
    public void updateBalance(Connection connection,String name,double balance){
        try{

            String sql = "update account set balance=balance+? where name=?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setDouble(1,balance);
            preparedStatement.setString(2,name);
            preparedStatement.executeUpdate();
        }catch (Exception e){

        }
    }
}

maven工程目錄預覽

Demo4中存在的問題延伸
當前所有對Connection的操作都在Service層進行處理
需要把所有對Connection操作隱藏起來

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章