JDBC_事务机制
文章目录
一、事务的基本知识
1、JDBC的事务是自动提交的,什么是自动提交?
只要执行一条DML语句,则自动提交一次。这是JDBC默认的事务行为。
但是在实际的业务中,通常都是N条DML语句共同联合才能完成的,必须保证它们这些DML语句在同一个事务中同时成功或者同时失败。
2、JDBC只要执行任意一条DML语句,就提交一次。
3、满足事务需要把默认的自动提交改为手动提交。
在执行完事务(一次可以有多个DML语句)的所有操作后手动提交即可。若成功,则本事务中的DML语句一起成功,若失败,则所有的都失败(需要rollback来保证数据的安全性)!
4、事务的四大特性(ACID)
Atomicity 原子性
——事务在全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行(就回滚)。Consistency 一致性
——几个并行执行的事务,其执行结果必须与按照某一顺序串行执行的结果相一致。(一个事务中,不同的执行顺序会导致不同的执行结果,因此需要考虑应该按照什么顺序执行)Isolation 隔离性
——事物的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。(主要就是事务执行的中间各个过程结果其它的事务不需要知道是如何执行的。)Durability 持久性
—— 对于任意已提交的事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。(不被丢失的前提是此事务已经进行过提交,并成功。)
二、事务的作用&简单应用
事务提供了一种机制,可用来将一系列数据库更改归入一个逻辑操作。更改数据库后,所做的更改可以作为一个单元进行提交或取消。事务可确保遵循原子性、一致性、隔离性和持续性(ACID)这几种属性,以使数据能够正确地提交到数据库中。
作用:
1、为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
2、当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
使用事务机制的好处非常明显,例如银行转账之类的交易操作中,事务有着重要的作用。事务的成功取决于事务单元帐户相互依赖的操作行为是否能全部执行成功,只要有一个操作行为失败,整个事务将失败。例如:客户A和客户B的银行账户金额都是10000元人民币,客户A需要把自己帐户中的5000元人民币转到客户B的账户上。这个过程看似简单,实际上涉及了一系列的数据库操作,可以简单地视为两步基本操作,即从客户A帐户的金额中扣除5000元人民币,以及将客户B帐户中金额添加5000元人民币。假设第1步数据库操作成功,而第二步失败的话,将导致整个操作失败,并且客户A帐户金额将被扣除5000元人民币。事务机制可以避免此类情况,以保证整个操作的完成,如果某步操作出错,之前所作的数据库操作将全部失效。
下面通过银行转账简单例子进行说明。
创建简单数据表:
drop table if exists t_act;
create table t_act(
actno int,
balance double(7,2)
);
insert into t_act values(111,20000);
insert into t_act values(222,20022);
commit;
实例应用代码:
package demo;
import java.sql.*;
/**
* @description: JDBC事务机制例子
* @author: Grape_Pip
*/
public class TransactionJDBCDemo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
// ResultSet rs = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2、连接数据库
String url = "jdbc:mysql://localhost:3306/myemployees?autoReconnect=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true";
String user = "root";
String password = "root";
conn = DriverManager.getConnection(url, user, password);
/*
* 将自动提交机制修改为手动提交!!!!!
* */
conn.setAutoCommit(false);
// 3、获取预编译的数据库操作对象
String sql = "update t_act set balance= ? where actno= ?";
pstmt = conn.prepareStatement(sql);
pstmt.setDouble(1, 10000);
pstmt.setInt(2, 111);
int count = pstmt.executeUpdate();
//如果在此中断,下面的更新语句不执行时,上面的语句会默认执行并提交,所以,若想让上下操作满足事务,必须设置其提交为手动提交
pstmt = conn.prepareStatement(sql);
pstmt.setDouble(1, 10000);
pstmt.setInt(2, 222);
count+=pstmt.executeUpdate();
// 程序能走到这里说明以上程序执行成功,事务结束,手动提交数据
conn.commit();
System.out.println(count==2?"转账成功":"转账失败");
} catch (Exception e) {
// 为了保证数据的安全,遇到异常,我们必须回滚,至少保证修改前的数据的安全性
if (conn!=null){
try{
conn.rollback();
}catch(SQLException e1){
e1.printStackTrace();
}
}
e.printStackTrace();
} finally {
// 6、释放资源
if (pstmt != null) {
try {
pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
}
根据上述的银行栗子,可以简单了解事务的一些作用以及特性。具体的应用说明已标注在代码的注释中啦。
(如果对JDBC基础6步感兴趣的,可以移步至JDBC基础编程六步_应用实例!)