事务处理
一、定义
事务就是所有的操作要么一起成功,要么一起失败。
事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabilily)4个特性,这4个特性也被称为ACID特性。
(1)原子性
原子性是指事务最小的单元,是不可再分割的单元,相当于一个个小的数据库操作,这些操作必须同时完成,如果有一个失败了,则一切的操作将全部失败。
(2)一致性
一致性指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现了错误,则回到最原始的状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。
(3)隔离性
多个事务可以同时进行并且彼此之间无法访问,只有当事务完成最终操作时,才可以看见结果。
(4)持久性
当一个事务完成后,操作的结果保存在磁盘中,永远不会被回滚。
二、MySQL对事务的支持
在数据库操作中,把每一个连接到此数据库上的用户成为一个session。对于一个session,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();
}
}
上一篇: SpringCloud集成分布式事务LCN (一)
下一篇: TCC补偿切面核心代码实现