JDBC 事务
要么都成功,要么都失败
ACID原则:保证数据的安全
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
转账:
A 1000
B 1000
A(900) --100--> B(1100)
假设转账的过程中服务器崩了
当我们想在工程中随时随地测试时,而不需要写main函数才能执行时,我们可以用Junit来实现
Junit单元测试
依赖
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
简单使用
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行
@Test
public void test(){ System.out.println("Hello");
}
运行效果 成功/失败
搭建一个环境
测试事务
我们来做一个Demo 测试一个JDBC的事务,就拿上面的例子,A B开始都有1000块钱,
A转给B 100 元
用事务机制来避免转钱多过程中发生失败
package com.lding.test;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @program: javaweb-jdbc
* @description:
* @author: 王丁
* @date: 2021-11-03 20:50
**/
public class TestJdbc3 {
//junit的用户啊
@Test
public void test() {
String url="jdbc:mysql://localhost:3306/JDBC?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSl=true";
String username="root";
String password="wd123456";
//1.加载驱动 抛出异常
Connection connection=null;
try {
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库 connection 代表数据库
connection = DriverManager.getConnection(url, username, password);
//3.通知数据库开启事务 =false是开启 =true是关闭
connection.setAutoCommit(false);
String sql="update account set money=money-100 where name='A'";
connection.prepareStatement(sql).executeUpdate();
//制造错误
// int i=1/0;
String sql2="update account set money=money+100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上两个SQL都执行成功了就提交事务
System.out.println("success");
}
catch (Exception e) {
try {
//如果出现异常就通知数据库回滚事务
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
当程序中间加入1/0 时,
可以观察到数据库中的A B金额都不变
如果删去了事务机制
connection.setAutoCommit(false);
可以观察到A的钱少了100 B的钱却没有+100
所以有事务机制,让中间崩溃的情况得到了回滚,才保证了AB金额不变
如果前面事件都没有异常,才会执行到commit提交事务,
如果前面有异常了 则会在异常处理中进行回滚操作