JDBC進行事務管理
事務的四個特征:
原子性 : 是指事務中包含的操作都被看做是一個邏輯單元
一致性: 開始前和結束后數據庫都處於一致性狀態
隔離性: 對數據庫修改的多個事務是彼此隔離的
持久性 事務完成之后對系統的影響是永久的
現舉一個例子:有兩張表,一張是user表,一張是地址表,user表和address表通過user_id關聯。現在我要插入一個人的信息,需要向兩個表中插入數據,如下:
insert into tbl_user(id,name,password,email) values(10,'xiongda','123','xiongda@qq.com')
insert into tbl_address(id,city,country,user_id) values(1,'hangzhou','china',10)
現在存在一個問題時,第二條語句的id與表中其他數據重復,存在了主鍵沖突。如果不加上事務管理,那么就只能導致user表插入了數據,但是address表就不能插入數據。
我們把這兩個表的插入操作看作是一個事務,這也就破壞了事務的一致性。
所以我們要做到,要么都插入,要么都不插入,也就是滿足事務的原子性。
JDBC中實現事務管理的代碼如下:
public class TransactionTest { public static Connection getConnection(){ Connection conn=null; try { Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); conn=(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=FALSE&serverTimezone=UTC","root","xb199795"); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } public static void insertUser(Connection conn) throws SQLException { String sql="insert into tbl_user(id,name,password,email)"+ "values(10,'xiongda','123','xiongda@qq.com')"; Statement st=conn.createStatement(); int count=st.executeUpdate(sql); System.out.println("向用戶表插入了"+count+"條記錄!"); } public static void insertAddress(Connection conn) throws SQLException { String sql="insert into tbl_address(id,city,country,user_id)"+ "values(1,'hangzhou','china',10)"; Statement st=conn.createStatement(); int count=st.executeUpdate(sql); System.out.println("向地址表插入了"+count+"條記錄!"); } public static void main(String[] args) { Connection conn =getConnection(); try { conn.setAutoCommit(false); insertUser(conn); insertAddress(conn); conn.commit(); } catch (SQLException e) { System.out.println("************事務處理出現異常***********"); e.printStackTrace(); try { conn.rollback(); System.out.println("*********事務回滾成功***********"); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); }finally { try { conn.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } }
user表中也沒有新增數據。