在使用原生jdbc的时候,如何开启一个事务呢,相信很多新手也是不知所措,我将会在之后学习中将自己遇到的问题分享出来,希望能够让你们少踩坑,使用数据库,首先肯定用到jdbc驱动
如果是eclipse,之前的文章有讲过,idea直接添加坐标即可(8.0版本的直接版本号)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
public class Test {
public static void main(String[] args) throws ClassNotFoundException{
Connection conn = null;
PreparedStatement ps = null;
try {
/**
* 数据库中的user表中字段是id和money,主键是id
* 代码演示的是转账,如果在赚钱过程中发送异常,那么转账要么都成功,要么都失败
* mysql5.0的驱动 com.mysql.jdbc.Driver
*/
Class.forName("com.mysql.cj.jdbc.Driver");
/**
* useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
* 这是mysql8.0之后需要设置时区才可以使用,否则会报错
* 在使用jdbc的时候可能没有问题,但是使用数据库连接池的时候就会编译报错(在阿里数据源中是报错的)
*/
String url = "jdbc:mysql://127.0.0.1:3306/{你的数据库名}?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
String username = "{你的数据库账号}";
String password = "{你的数据库密码}";
/**
* {}代表是一参数,如 username = root
*/
conn = DriverManager.getConnection(url, username, password);
System.out.println(conn);
// 关闭事务自动提交
conn.setAutoCommit(false);
String sql = "update test set money = money-? where id = ?";
int money=300;
// 预编译,可以防止SQL注入,Statement基本上已经不怎么使用了
ps = conn.prepareStatement(sql);
ps.setString(1,money+"");
ps.setString(2, 1+"");
ps.execute();
sql = "update test set money = money+? where id = ?";
ps=conn.prepareStatement(sql);
ps.setString(1, money+"");
ps.setString(2, 2+"");
// 可以在这里写一个异常测试一下,如 int sum=5/0;如果没有设置事务则数据库转账的人钱少了,而被转的人钱没有变化
// 只有两个语句都执行成功之后,数据库信息才会发生变化
ps.execute();
//提交事务
conn.commit();
}catch (Exception e){
try {
// 当发生异常的时候,进行事务回滚,恢复原来的数据
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.getStackTrace();
}
try {
if (ps != null) {
ps.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
一定要记得导入对应的jar包,否则会报空指针错误