1:事務的概述:
什么是事務:事務指的是邏輯上的一組操作,組成這組操作的各個單元要么全都成功,要么全都失敗.
事務作用:保證在一個事務中多次操作要么全都成功,要么全都失敗.
2:創(chuàng)建一個maven工程鸵鸥,進行如下導包操作:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
</dependencies>
3:事務有四大特性:
原子性:強調事務的不可分割.
一致性:事務的執(zhí)行的前后,數據的完整性保持一致.
隔離性:一個事務在執(zhí)行的過程中,不應該受到其他事務的干擾.
-
持久性:事務一旦結束,數據就持久到數據庫中.
4:如果不考慮事務的隔離性,引發(fā)一些安全性問題:
讀問題:三類- 臟讀:一個事務讀到了另一個事務未提交的數據.
- 不可重復讀:一個事務讀到了另一個事務已經提交(update)的數據.引發(fā)一個事務中的多次查詢結果不一致.
- 虛讀/幻讀 :一個事務讀到了另一個事務已經提交的(insert)數據.導致多次查詢的結果不一致
5:解決讀問題:
設置事務的隔離級別:
read uncommitted :臟讀疾宏,不可重復讀,虛讀都可能發(fā)生.
read committed :避免臟讀,但是不可重復讀和虛讀有可能發(fā)生.
repeatable read :避免臟讀和不可重復讀,但是虛讀有可能發(fā)生的.
serializable :避免臟讀,不可重復讀和虛讀.(串行化的-不可能出現事務并發(fā)訪問)
安全性:serializable > repeatable read > read committed > read uncommitted
效率 :serializable< repeatable read < read committed < read uncommitted
MYSQL :repeatable read
Oracle :read committed
6:轉賬案例
package com.com.pp.Money;
import com.com.pp.util.JdbcUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Pay {
public static void main(String[] args) throws SQLException {
Connection connection = JdbcUtil.getConnection();
//事物提交
connection.setAutoCommit(false);//默認不是自動提交
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
outMoney("a",1000);
int i=1/0;//異常,保證轉出和轉入同時執(zhí)行
inMoney("b",1000);
/*
* 同時成功和同時失敗
* */
connection.commit();
connection.close();
}
/*
* 轉入
* */
public static void inMoney(String name,double money) throws SQLException {
Connection connection=null;
PreparedStatement preparedStatement=null;
//實例化
String sql="update account set money=money+? where name=?";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql);
preparedStatement.setDouble(1,money);
preparedStatement.setString(2,name);
preparedStatement.executeUpdate();
JdbcUtil.closeResouce(connection,preparedStatement,null);
}
/*
* 轉出
* */
public static void outMoney(String name,double money) throws SQLException {
Connection connection=null;
PreparedStatement preparedStatement=null;
//實例化
Connection connection1 = JdbcUtil.getConnection();
String sql="update account set money=money-? where name=?";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql);
preparedStatement.setDouble(1,money);
preparedStatement.setString(2,name);
preparedStatement.executeUpdate();
JdbcUtil.closeResouce(connection,preparedStatement,null);
}
}