廖雪峰Java15JDBC编程-3JDBC接口-3JDBC事务

Posted csj2018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了廖雪峰Java15JDBC编程-3JDBC接口-3JDBC事务相关的知识,希望对你有一定的参考价值。

数据库事务:Transaction

  • 若干SQL语句构成的一个操作序列
  • 要么全部执行成功
  • 要么全部执行不成功

数据库事务具有ACID特性:

Atomicity:原子性 一个事务虽有若干SQL语句构成,但它本身是一个原子操作,要么全部成功,要么全部失败


Consistency:一致性 一个事务在开始前或结束之后,数据库的数据是完整的,不存在冲突和数据不一致的情况


Isolation:隔离型 多个事务并发执行的时候,事务之间是隔离的,一个事务不影响其他事务运行的结果


Durability:持久性 一个事务一旦成功完成,这个事务对数据库的更改会持久的保留在数据库中,并且不会被回滚。

为什么需要数据库事务?

例子:转账操作,把100元从小明的账户转给小红。

update accounts set balance = balance - 100 while id = 1;
update accounts set balance = balance + 100 while id = 2;

但如果在执行万第一条update语句后,由于各种原因,第二条update没有执行,会出现什么结果呢?
小明的钱已经扣了,小红的钱却未加上,这个时候应用逻辑出现了不一致的情况。
而使用数据库事务可以保证多个SQL语句全部执行或全部取消。即结果只有2个:
1.小明的钱成功转给了小红
2.小明的钱没有成功转给小红,退回小明账户。小明和小红的钱保持不变。

事务分离级别:是由数据库许多个连接同时执行事务引起的。
在Java程序中,当一个线程操作一个数据库连接的时候,另一个线程可能也在通过一个数据库连接更新数据。他们之间就会遇到隔离级别的问题。
事务隔离会遇到3个问题:
1.脏读
2.非重复复读
3.幻读

package com.feiyangedu.sample.pop3;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcTx 
    static final String JDBC_URL = "jdbc:mysql://localhost:13306/test0828?characterEncoding=utf8&useSSL=false&serverTimeZone=UTC";
    static final String JDBC_USER = "root";
    static final String JDBC_PASSWORD = "123456";

    public static void main(String[] args) throws SQLException
        List<Student> students = getAllStudents();
        for(Student student:students)
            System.out.println(student);
        
        Connection conn = null;
        try
            conn = getConnection();
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            conn.setAutoCommit(false);
            updateName(conn, students.get(0).id, "Bob");
            updateName(conn, students.get(1).id, "Alice");
            conn.commit();
            System.out.println("commit ok");
        catch (Exception e)
            e.printStackTrace();
            conn.rollback();
        finally 
            if(conn != null)
                try
                    conn.setAutoCommit(true);
                    conn.close();
                catch (SQLException e)
                    System.err.println(e);
                

            
        
        System.out.println("第一次事务结束后");
        students = getAllStudents();
        for(Student student:students)
            System.out.println(student);
        
        try
            conn = getConnection();
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            conn.setAutoCommit(false);
            updateName(conn, students.get(0).id,"张三");
            updateName(conn, students.get(1).id,"李四");
            throw new RuntimeException("第二次事务出错");
        catch (Exception e)
            conn.rollback();
        finally 
            if(conn != null)
                try
                    conn.setAutoCommit(true);
                    conn.close();
                catch (Exception e)
                    System.err.println(e);
                
            
        
        System.out.println("第二次事务结束");
        students = getAllStudents();
        for(Student student:students)
            System.out.println(student);
        
    
    static void updateName(Connection conn, long id, String name) throws SQLException
        try(PreparedStatement ps = conn.prepareStatement("update students set name=? where id=?"))
            ps.setObject(1, name);
            ps.setObject(2, id);
            ps.executeUpdate();
        
    
    static List<Student> getAllStudents() throws SQLException
        try(Connection conn = getConnection())
            try(PreparedStatement ps = conn.prepareStatement("select * from students"))
                ResultSet rs = ps.executeQuery();
                List<Student> list = new ArrayList<>();
                while(rs.next())
                    long id = rs.getLong("id");
                    long classId = rs.getLong("class_id");
                    String name = rs.getString("name");
                    String gender = rs.getString("gender");
                    list.add(new Student(id,classId,name,gender));
                
                return list;
            
        
    

    static Connection getConnection() throws SQLException 
        return DriverManager.getConnection(JDBC_URL,JDBC_USER,JDBC_PASSWORD);
    

技术图片

以上是关于廖雪峰Java15JDBC编程-3JDBC接口-3JDBC事务的主要内容,如果未能解决你的问题,请参考以下文章

廖雪峰Java15JDBC编程-3JDBC接口-2JDBC更新

廖雪峰Java2面向对象编程-4抽象类和接口-2接口

廖雪峰Java6 IO编程-2input和output-7序列化

廖雪峰Java2面向对象编程-4抽象类和接口-1抽象类

廖雪峰Java13网络编程-1Socket编程-2TCP编程

廖雪峰Java13网络编程-3其他-1HTTP编程