欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

事务处理

程序员文章站 2022-07-12 17:03:12
...

一、定义

事务就是所有的操作要么一起成功,要么一起失败。

事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabilily)4个特性,这4个特性也被称为ACID特性。

(1)原子性

原子性是指事务最小的单元,是不可再分割的单元,相当于一个个小的数据库操作,这些操作必须同时完成,如果有一个失败了,则一切的操作将全部失败。

(2)一致性

一致性指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现了错误,则回到最原始的状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。

(3)隔离性

多个事务可以同时进行并且彼此之间无法访问,只有当事务完成最终操作时,才可以看见结果。

(4)持久性

当一个事务完成后,操作的结果保存在磁盘中,永远不会被回滚。

二、MySQL对事务的支持

在数据库操作中,把每一个连接到此数据库上的用户成为一个session。对于一个session,MySQL中对事务有 如下支持命令:

MySQL中对事务的支持命令
SET AUTOCOMMIT=0 取消自动提交
SET AUTOCOMMIT=1 打开自动提交
START TRANSACTION 启动事务
BEGIN 启动事务,同上
COMMIT 提交事务
ROLLBACK 回滚全部操作
SAVEPOINT 事务保存点名称 设置事务保存点
ROLLBACK TO SAVEPOINT 保存点名称 回滚操作到保存点

在MySQL中,应用事务处理,按照如下步骤:

(1)取消自动提交

SET AUTOCOMMIT=0

(2)开启事务

START TRANSACTION
或
BEGIN

(3)编写数据库更新语句

如增加、修改、删除,并且可以在编写的更新语句之间记录事务的保存点,使用SAVEPOINT指令。

(4)提交事务

COMMIT

(5)事务回滚

如果发现执行的SQL语句有错误,则使用ROLLBACK命令全部撤销,或者使用ROLLBACK TO SAVEPOINT 记录点,让其回滚到指定的位置。

当一个事务进行时,其他的session时无法看到此事务的操作状态的。即此session对数据库所做的一切修改,如果没有提交事务,其他session时无法看见此session的操作结果的。

三、执行JDBC的事务处理

在JDBC中,如果要想进行事务处理,也需要按照指定的步骤完成:

1.取消Connection中设置的自动提交

conn.setAutoCommit(false)

2.如果批处理操作成功,则执行提交事务

conn.commit()

3.如果操作失败,则坑定会引发异常,在异常处理中让事务回滚

conn.rollback()

4.如果需要,可以设置Savepoint

Savepoinit sp=conn.setSavepoint()

四、实例

(1)事务基本操作

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TranDemo01{
	//mysql数据库驱动
	public static final String DBDRIVER="com.mysql.cj.jdbc.Driver";
	//mysql数据库连接地址
	public static final String DBURL="jdbc:mysql://localhost:3306/mldn?useSSL=false&serverTimezone=UTC";
	//mysql数据库连接用户名
	public static final String DBUSER="root";
	//mysql数据库连接密码
	public static final String DBPASS="root";

	public static void main(String[] args) throws Exception{
		//1、加载数据库驱动
		Class.forName(DBDRIVER);
		//2、获取数据库连接
		Connection conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);
		//3、取消自动提交
		conn.setAutoCommit(false);
		//4、实例化Statement对象,并进行批处理
		Statement stmt=conn.createStatement();
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('a','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('b','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('c','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('d','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('e','a',1,'男','1975-03-05')");
		try{
			int temp[]=stmt.executeBatch();
			System.out.println("更新了"+temp.length+"条数据。");
			conn.commit();
		}catch(Exception e){
			try{
				conn.rollback();
			}catch(Exception ex){}
		}
		//5、关闭数据库连接
		stmt.close();
		conn.close();
	}
}

(2)加入Savepoint

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.Savepoint;
public class TranDemo01{
	//mysql数据库驱动
	public static final String DBDRIVER="com.mysql.cj.jdbc.Driver";
	//mysql数据库连接地址
	public static final String DBURL="jdbc:mysql://localhost:3306/mldn?useSSL=false&serverTimezone=UTC";
	//mysql数据库连接用户名
	public static final String DBUSER="root";
	//mysql数据库连接密码
	public static final String DBPASS="root";

	public static void main(String[] args) throws Exception{
		//1、加载数据库驱动
		Class.forName(DBDRIVER);
		//2、获取数据库连接
		Connection conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);
		//3、取消自动提交
		conn.setAutoCommit(false);
		//4、实例化Statement对象,并进行批处理
		Statement stmt=conn.createStatement();
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('a','a',1,'男','1975-03-05')");
		Savepoint sp=conn.setSavepoint();
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('b','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('c','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('d','a',1,'男','1975-03-05')");
		stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday) VALUES('e','a',1,'男','1975-03-05')");
		try{
			int temp[]=stmt.executeBatch();
			System.out.println("更新了"+temp.length+"条数据。");
			conn.commit();
		}catch(Exception e){
			try{
				conn.rollback(sp);
			}catch(Exception ex){}
		}
		//5、关闭数据库连接
		stmt.close();
		conn.close();
	}
}