首页 > 代码库 > 关于mysql事务提交

关于mysql事务提交

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事务提交