JDBC中数据库事务实现:
1、事务的概念:
数据库事务就是一种SQL语句执行的缓存机制,不会单条执行完毕就更新数据库数据,最终根据缓存内的多条语句执行结果统一判定!
一个事务内所有语句都成功及事务成功,我们可以触发commit提交事务来结束事务,更新数据! 一个事务内任意一条语句失败,及事务失败,我们可以触发rollback回滚结束事务, 数据回到事务之前状态!
(适用于银行转账操作)
2、优势:
允许我们在失败情况下,数据回归到业务之前的状态!
3、适用场景:
经典的转账案例,转账业务(加钱和减钱)
批量删除(涉及多个删除)
批量添加(涉及多个插入)
4、事务的特性:
1. 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2. 一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3. 隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4. 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
5、事务的类型:
自动提交 : 每条语句自动存储一个事务中,执行成功自动提交,执行失败自动回滚! (MySQL)
手动提交: 手动开启事务,添加语句,手动提交或者手动回滚即可!
针对自动提交: 关闭自动提交即可,多条语句添加以后,最终手动提交或者回滚! (推荐)
6、呼应JDBC技术:
try{
//开启手动提交事务(关闭事务自动提交)
connection.setAutoCommit(false);
//执行数据库动作(单一数据库动作curd)
bankDao.add(addaccount,money,connection);
System.out.println("------------");
bankDao.sub(subaccount,money,connection);
//不报错,提交事务
connection.commit();
}catch (Exception e){
//事务回滚
connection.rollback();
throw e;
}finally {
connection.close();
}
代码结构设计:
7、事务实现:
Dao层:
public class BankDao {
/**
* 加钱的数据库操作方法
* @param account 加钱的账号
* @param money 加钱的金额
* @param connection
*/
public void add(String account, int money, Connection connection) throws Exception {
//3.编写SQL语句
String sql="update t_bank set money = money + ? where account = ?;";
//4.创建preparedStatement对象,并预编译sql语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.占位符赋值
preparedStatement.setInt(1,money);
preparedStatement.setString(2,account);
//6.发送SQL语句
preparedStatement.executeUpdate();
//7.输出结果
System.out.println("加钱成功!");
//8.关闭资源
preparedStatement.close();
}
/**
* 减钱的数据库操作方法
* @param account 减钱的账号
* @param money 减钱的金额
* @param connection
*/
public void sub(String account, int money, Connection connection) throws SQLException {
//3.编写SQL语句
String sql="update t_bank set money = money - ? where account = ?;";
//4.创建preparedStatement对象,并预编译sql语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.占位符赋值
preparedStatement.setInt(1,money);
preparedStatement.setString(2,account);
//6.发送SQL语句
preparedStatement.executeUpdate();
//7.输出结果
System.out.println("减钱成功!");
//8.关闭资源
preparedStatement.close();
}
}
Service类:
public class BankService {
/**
* TODO:
* 事务添加是在业务方法中!
* 利用try catch代码块,开启事务和事务提交、事务回滚
* 将connection传入dao层,dao层只负责使用,不需要关闭
* 在finally中关闭connection资源
* @param addaccount
* @param subaccount
* @param money
* @throws Exception
*/
public void transfer(String addaccount,String subaccount,int money) throws Exception {
BankDao bankDao=new BankDao();
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.建立连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_study?user=root&password=mysql");
try{
//开启手动提交事务(关闭事务自动提交)
connection.setAutoCommit(false);
//执行数据库动作
bankDao.add(addaccount,money,connection);
System.out.println("------------");
bankDao.sub(subaccount,money,connection);
//不报错,提交事务
connection.commit();
}catch (Exception e){
//事务回滚
connection.rollback();
throw e;
}finally {
connection.close();
}
}
}
测试类:
public class BankTest {
public static void main(String[] args) throws Exception {
BankService bank=new BankService();
bank.transfer("123","456",500);
}
}
关于事务:
1、事务是指在数据库中进行一系列相关操作的一个完整的执行单元。在执行过程中,要么全部执行成功,要么全部失败回滚。一般来说,一个事务包含多个操作,例如插入、修改和删除。
2、事务具有原子性、一致性、隔离性和持久性特征。原子性指事务是一个不可分割的单元,要么整个事务操作成功,要么全部失败回滚;一致性指事务执行前和执行后,数据库必须保持一致性状态;隔离性指多个并发事务之间是互相隔离的,一个事务执行时,它所读取的数据和操作的数据对其他事务是隔离的;持久性指在事务提交后,其对数据库所作的修改是永久性的,即使发生系统崩溃,数据也不会丢失。
3、实际应用中,我们通过数据库的 ACID(原子性、一致性、隔离性、持久性)特性来保证事务的正确执行。事务的应用场景非常广泛,例如转账、在线购物等。在这些场景中,我们都需要保证事务的正确执行,避免出现脏数据和不一致情况。