<tbody id="86a2i"></tbody>


<dd id="86a2i"></dd>
<progress id="86a2i"><track id="86a2i"></track></progress>

<dd id="86a2i"></dd>
<em id="86a2i"><ruby id="86a2i"><u id="86a2i"></u></ruby></em>

    <dd id="86a2i"></dd>

    JDBC事務相關方法簡介

    本文將借助示例,簡單講解下JDBC操作Pg事務的流程。

    首先來簡單講解下事務的定義:為了確保兩個(多個)數據庫操作都生效,或者兩個操作都不發生,可以使用事務。根據定義,事務是作為單個單元執行的一組語句。換句話說,要么所有語句都成功執行,要么沒有執行。

    禁用自動提交模式

    當建立與PostgreSQL數據庫的連接時,它處于自動提交模式。這意味著每個SQL語句都被視為事務并自動提交。

    如果要在事務中封裝一個或多個語句,則必須禁用自動提交模式。為此,我們可以調用Connection.setAutoCommit()方法來修改SQL提交模式:

    Connection.setAutoCommit(false);
    

    最佳做法是僅對事務模式禁用自動提交模式。它避免為多個語句保留數據庫鎖。

    提交事務

    要提交事務,請調用Connection對象的commit方法,如下所示:

    Connection.commit();
    

    當調用commit()方法,所有前面的SQL語句作為一個單元一起提交。

    回滾事務

    既然使用了事務,那我們肯定會有回滾的時候,我們可以使用rollback()方法來中止當前事務并將值恢復為原始值。

    Connection.rollback();
    

    PostgreSQL JDBC 事務示例

    讓我們舉一個使用JDBC API執行PostgreSQL事務的示例。

    首先,創建一個表示ProRank的實體類,如下所示:

    import lombok.Data;
    @Data
    public class ProRank {
        Integer id;
        String name;
        String team;
        String line;
        Integer rank;
    }
    

    然后,編寫以下代碼,供我們測試事務操作。

    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    import java.sql.*;
    @SpringBootTest
    class JdbcTrasationTests {
        private final String url = "jdbc:p6spy:postgresql://localhost:5432/postgres";
        private final String user = "postgres";
        private final String password = "112233";
        /**
         * 連接PostgreSql數據庫
         *
         * @return Connection
         * @throws SQLException
         */
        public Connection connect() throws SQLException {
            return DriverManager.getConnection(url, user, password);
        }
        @Test
        void testTrasation() {
            ProRank proRank = new ProRank();
            proRank.setLine("Mid");
            proRank.setName("Faker");
            proRank.setTeam("T1");
            proRank.setRank(0);
            //調用
            addProAndUpdateRank(proRank,2222);
        }
        /**
         * 關閉一個AutoCloseable對象
         *
         * @param closeable
         */
        private void close(AutoCloseable closeable) {
            try {
                if (closeable != null) {
                    closeable.close();
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        /**
         * 插入一條選手記錄,更新他的rank值
         *
         * @param proRank
         * @param rank
         */
        public void addProAndUpdateRank(ProRank proRank, Integer rank) {
            Connection conn = null;
            PreparedStatement pstmt = null;
            PreparedStatement pstmt2 = null;
            ResultSet rs = null;
            // 插入一條數據
            String SQL = "INSERT INTO pro_rank(name,team,line,rank) VALUES(?,?,?,?)";
            // 更新他的rank值
            String SQLUpdateRank = "UPDATE pro_rank SET rank = ? WHERE id = ?;";
            int id = 0;
            try {
                // 鏈接數據庫
                conn = connect();
                conn.setAutoCommit(false);
                // 插入一條數據
                pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
                pstmt.setString(1, proRank.getName());
                pstmt.setString(2, proRank.getTeam());
                pstmt.setString(3, proRank.getLine());
                pstmt.setInt(4, proRank.getRank());
                int affectedRows = pstmt.executeUpdate();
                // 判斷是否生效
                if (affectedRows > 0) {
                    // 獲取返回的id
                    rs = pstmt.getGeneratedKeys();
                    if (rs.next()) {
                        id = rs.getInt(1);
                        if (id > 0) {
                            pstmt2 = conn.prepareStatement(SQLUpdateRank);
                            pstmt2.setInt(2, id);
                            pstmt2.setInt(1, rank);
                            pstmt2.executeUpdate();
                        }
                    }
                } else {
                    // 如果新增數據失敗,回滾
                    conn.rollback();
                }
                // 提交事務
                conn.commit();
                System.out.println("插入選手數據成功!更新選手rank成功,數據id:" + id);
            } catch (SQLException sqlException) {
                System.out.println(sqlException.getMessage());
                sqlException.printStackTrace();
                // 回滾事務
                System.out.println("回滾事務...");
                try {
                    if (conn != null) {
                        conn.rollback();
                    }
                } catch (SQLException e) {
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                }
            } finally {
                close(rs);close(pstmt);close(pstmt2);close(conn);
            }
        }
    }
    

    讓我們看一下上面的代碼,他包含三個方法

    connect()?方法建立與數據庫連接,并返回連接對象。

    close()?方法關閉數據庫操作可關閉的對象,如Resultset、Statement和Connection。

    addProAndUpdateRank()方法插入新的選手,并在事務中更新選手的rank字段。此方法包含邏輯如下:

    • 首先,在pro_rank表中插入一條新的選手數據。
    • 接下來,獲取新插入的選手數據的id
    • 然后,更新插入選手的rank值。
    • 之后,如果步驟2和3均成功,則提交事務。否則,回滾事務
    • 最后,關閉ResultSet、PreparedStatement和Connection對象。

    如果我們在第一個場景中執行程序,我們會得到以下結果:

    插入選手數據成功!更新選手rank成功,數據id:14
    

    PostgreSql?JDBC事務操作方法詳解

    我們可以通過查詢pro_rank表格,來查看上述代碼執行結果:

    SELECT * FROM "public"."pro_rank" LIMIT 1000 OFFSET 0;
    

    PostgreSql?JDBC事務操作方法詳解

    現在,讓我們測試一下事務回滾的情況,比如,我們可以在插入一條數據的時候,將name字段賦值為超出數據庫長度的字串,運行程序結果如下:

    PostgreSql?JDBC事務操作方法詳解

    ERROR: value too long for type character varying(7)

    PostgreSql?JDBC事務操作方法詳解

    事務將回滾,并且沒有任何內容插入pro_rank表

    以上就是PostgreSql JDBC事務操作方法詳解的詳細內容,更多關于PostgreSql JDBC事務操作的資料請關注其它相關文章!

    原文地址:https://juejin.cn/post/7166032867829481485

    相關文章:

    免费一级a片在线播放视频|亚洲娇小性XXXX色|曰本无码毛片道毛片视频清|亚洲一级a片视频免费观看
    <tbody id="86a2i"></tbody>

    
    
    <dd id="86a2i"></dd>
    <progress id="86a2i"><track id="86a2i"></track></progress>

    <dd id="86a2i"></dd>
    <em id="86a2i"><ruby id="86a2i"><u id="86a2i"></u></ruby></em>

      <dd id="86a2i"></dd>