下一篇:21【JDBC操作数据库元数据】
20【JDBC的事务处理】
1.1 JDBC的事务处理
之前我们是使用MySQL的命令来操作事务。接下来我们使用JDBC来操作银行转账的事务。
- 数据准备:
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10),
money double
);
-- 添加数据
INSERT INTO account (name, money) VALUES ('a', 1000), ('b', 1000);
select * from account;
1.1.1 事务相关API
- Connection中事务相关方法如下:
方法名 | 描述 |
---|---|
boolean getAutoCommit() | 获取本次连接是否自动提交事务,默认true |
void setAutoCommit(boolean autoCommit) | 设置本次连接是否自动提交事务 |
void commit() | 提交事务 |
void rollback() | 回滚事务 |
int getTransactionIsolation() | 获取事务的隔离级别 |
void setTransactionIsolation(int level) | 设置事务的隔离级别 |
Savepoint setSavepoint() | 设置事务保存点 |
void rollback(Savepoint savepoint) | 回滚到保存点 |
1.1.2 案例测试
1)模拟转账业务
- 示例代码:
package com.dfbz.demo;
import com.dfbz.utils.JdbcUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author lscl
* @version 1.0
* @intro:
*/
public class Demo15_事务 {
/**
* 模拟事务
* @throws Exception
*/
@Test
public void test1() throws Exception{
//创建连接对象
Connection conn = null;
Statement stmt = null;
try {
conn = JdbcUtils.getConnection();
// 设置事务不要自动提交(手动提交,默认情况下,事务是自动提交的)
conn.setAutoCommit(false);
//创建语句对象
stmt = conn.createStatement();
//a扣钱
stmt.executeUpdate("update account set money=money-500 where name='a'");
// 模拟异常
// System.out.println(100 / 0);
// b加钱
stmt.executeUpdate("update account set money=money+500 where name='b'");
// 提交事务
conn.commit();
System.out.println("转账成功");
} catch (Exception e) {
try {
// 回滚事务
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
System.out.println("转账失败");
} finally {
JdbcUtils.close(conn, stmt);
}
}
}
2)事务隔离级别
Connection中有如下静态常量来规定隔离级别:
- TRANSACTION_READ_UNCOMMITTED(1):读未提交
- TRANSACTION_READ_COMMITTED(2):读已提交
- TRANSACTION_REPEATABLE_READ(4):可重复读
- TRANSACTION_SERIALIZABLE(8):串行化
测试代码:
/**
* 测试隔离级别
*
* @throws Exception
*/
@Test
public void test2() throws Exception {
Connection conn = JdbcUtils.getConnection();
//创建语句对象
Statement stmt = conn.createStatement();
/*
TRANSACTION_READ_UNCOMMITTED(1): 读未提交
TRANSACTION_READ_COMMITTED(2): 读已提交
TRANSACTION_REPEATABLE_READ(4): 可重复读
TRANSACTION_SERIALIZABLE(8): 串行化
*/
// 将本次连接的隔离级别设置为读未提交
conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
/*
先在其他窗口创建一个事务修改数据但不提交,
然后再断点执行下面代码,
看下是否能查询到其他事务没提交的数据
*/
ResultSet rs = stmt.executeQuery("select * from account");
while (rs.next()) {
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println("name: " + name);
System.out.println("money: " + money);
}
JdbcUtils.close(conn, stmt);
}
3)事务回滚点
- 测试代码:
/**
* 测试回滚点
*
* @throws Exception
*/
@Test
public void test3() throws Exception {
Connection conn = JdbcUtils.getConnection();
// 设置手动提交事务
conn.setAutoCommit(false);
//创建语句对象
Statement stmt = conn.createStatement();
stmt.executeUpdate("update account set money=900;");
// 设置保存点
Savepoint p1 = conn.setSavepoint();
stmt.executeUpdate("update account set money=800;");
// 设置保存点
Savepoint p2 = conn.setSavepoint();
stmt.executeUpdate("update account set money=700;");
// 回滚到p1保存点
conn.rollback(p1);
// 提交事务
conn.commit();
JdbcUtils.close(conn, stmt);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131691.html