標籤:blog io os ar java 資料 2014 on log
package com.itheima.trans;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.itheima.util.DBUtil;public class TransDemo {/* 建立mysql資料庫相關sql語句: create database day11; use day11; create table account( id int primary key auto_increment, name varchar(20), salary double ); insert into account values(null, 'a', 1000); insert into account values(null, 'b', 1000); */public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtil.getConn();conn.setAutoCommit(false);//設定自動事務提交為false//a給b轉賬-----a賬戶減去100塊錢;b賬戶增加100塊錢ps = conn.prepareStatement("update account set salary=salary-100 where name=?");ps.setString(1, "a");ps.executeUpdate();int i = 1 / 0;//設定異常ps = conn.prepareStatement("update account set salary=salary+100 where name=?");ps.setString(1, "b");ps.executeUpdate();conn.commit();} catch (Exception e) {e.printStackTrace();try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}} finally {DBUtil.close(conn, ps, rs);}}}
代碼解析:
預設情況下每執行一條sql語句,就是執行一次事務,也就是每一條sql語句的執行都會是一次事務的提交。
在這個例子中如果a給b轉賬,a賬戶減去100的sql語句執行成功,這時伴隨著一次的事務提交,資料庫中的a賬戶金額減去100;而再執行b的賬務增加100sql語句之前,出現了異常,這裡我設了一個除以零異常,此時程式終止,bsql語句不再執行。a賬戶扣了100,而b賬戶則金額不變。這時資料出錯。
解決方案是:通過conn.setAutoCommit(false);方法設定事務自動認可為false。這時每一次的sql語句執行完成後就不會提交事務,資料庫中的資料並不會發生改變,當倆個sql都執行完成,然後調用coon.commit();方法提交事務,此時資料庫中的資料才會真正的改變。如果中途發生異常,通過conn.rollback();方法復原,此時之前執行的sql語句的結果並不會提交。這樣資料就不會出錯了。
設定Savepoint:
package com.itheima.trans;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Savepoint;import com.itheima.util.DBUtil;public class TransDemo {/* 建立mysql資料庫相關sql語句: create database day11; use day11; create table account( id int primary key auto_increment, name varchar(20), salary double ); insert into account values(null, 'a', 1000); insert into account values(null, 'b', 1000); */public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;Savepoint point = null;try {conn = DBUtil.getConn();conn.setAutoCommit(false);//設定自動事務提交為false//a給b轉賬-----a賬戶減去100塊錢;b賬戶增加100塊錢ps = conn.prepareStatement("update account set salary=salary-100 where name=?");ps.setString(1, "a");ps.executeUpdate();ps = conn.prepareStatement("update account set salary=salary+100 where name=?");ps.setString(1, "b");ps.executeUpdate();point = conn.setSavepoint();int i = 1 / 0;//a給b轉賬-----a賬戶減去100塊錢;b賬戶增加100塊錢ps = conn.prepareStatement("update account set salary=salary-100 where name=?");ps.setString(1, "a");ps.executeUpdate();ps = conn.prepareStatement("update account set salary=salary+100 where name=?");ps.setString(1, "b");ps.executeUpdate();conn.commit();} catch (Exception e) {e.printStackTrace();try {if(point == null) {conn.rollback();} else {conn.rollback(point);conn.commit();}} catch (SQLException e1) {e1.printStackTrace();}} finally {DBUtil.close(conn, ps, rs);}}}
關於mysql事務提交