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); } } }
版权声明:本文博主原创文章。博客,未经同意不得转载。