一、事务管理
1.事务概述
事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败。
事务作用:保证在一个事务中多次操作,要么全都成功,要么全部失败。
一组:无论多少SQL语句,必须使用同一个连接对象操作,包括insert,update,delete,不包括select,因为select不改变原有数据
2.mysql事务操作
| sql语句 | 描述 |
|---|---|
| start transaction; | 开启事务 |
| commit; | 提交事务 |
| rollback; | 回滚事务 |
准备数据
# 创建一个表:账户表.
create database webdb;
# 使用数据库
use webdb;
# 创建账号表
create table account(
id int primary key auto_increment,
name varchar(20),
money double
);
# 初始化数据
insert into account values (null,'jack',10000);
insert into account values (null,'rose',10000);
insert into account values (null,'tom',10000);
操作:
MySQL中可以有两种方式进行事务的管理:
自动提交:MySQL默认自动提交。即执行一条sql语句提交一次事务。
手动提交:先开启,再提交
方式1:手动提交
start transaction;
update account set money=money-1000 where name='jack';
update account set money=money+1000 where name='rose';
commit;
#或者
rollback;
方式2:自动提交,通过修改mysql全局变量“autocommit”进行控制
show variables like '%commit%';
* 设置自动提交的参数为OFF:
set autocommit = 0; -- 0:OFF 1:ON
扩展:Oracle数据库事务不自动提交
3.JDBC事务操作
| Connection对象的方法名 | 描述 |
|---|---|
| conn.setAutoCommit(false) | 开启事务 |
| conn.commit() | 提交事务 |
| conn.rollback() | 回滚事务 |
//事务模板代码
public void demo01() throws SQLException{
// 获得连接
Connection conn = null;
try {
//#1 开始事务
conn.setAutoCommit(false);
//.... 加钱 ,减钱
//#2 提交事务
conn.commit();
} catch (Exception e) {
//#3 回滚事务
conn.rollback();
} finally{
// 释放资源
conn.close();
}
}
4.DBUtils事务操作
| Connection对象的方法名 | 描述 |
|---|---|
| conn.setAutoCommit(false) | 开启事务 |
| new QueryRunner() | 创建核心类,不设置数据源(手动管理连接) |
| query(conn,sql,handler,params)或update(conn,sql,params) | 手动传递连接 |
| DbUtils.commitAndClose(conn) | 提交并关闭连接 |
| DbUtils.rollbackAndClose(conn) | 回滚并关闭连接 |
二、案例分析

开发中,常使用分层思想
不同的层次结构分配不同的解决过程,各个层次间组成严密的封闭系统
不同层级结构彼此平等
分层的目的是:
解耦
可维护性
可扩展性
可重用性
不同层次,使用不同的包表示
com.baidu—— 公司域名倒写
com.baidu.dao—— dao层
com.baidu.service—— service层
com.baidu.domain—— javabean
com.baidu.utils—— 工具
三、代码实现
编写AccountService
public class AccountService {
/**
* 业务层转账的方法:
* @param outUser :付款人
* @param inUser :收款人
* @param money :转账金额
*/
public void transfer(String outUser, String inUser, int money) {
// 调用DAO:
AccountDao accountDao = new AccountDao();
try {
accountDao.outMoney(outUser, money);
// int d = 1/0;
accountDao.inMoney(inUser, money);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
编写AccountDao
public class AccountDao {
/**
* 付款的方法
* @param name
* @param money
* @throws SQLException
*/
public void outMoney(String name,int money) throws SQLException{
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写一个SQL:
String sql = "update account set money = money-? where name=?";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setInt(1, money);
pstmt.setString(2, name);
// 执行SQL:
pstmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
pstmt.close();
conn.close();
}
}
/**
* 收款的方法
* @param name
* @param money
* @throws SQLException
*/
public void inMoney(String name,int money) throws SQLException{
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写一个SQL:
String sql = "update account set money = money+? where name=?";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setInt(1, money);
pstmt.setString(2, name);
// 执行SQL:
pstmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
pstmt.close();
conn.close();
}
}
}
四、事务管理:传递Connection
修改service和dao,service将connection传递给dao,dao不需要自己获得连接
service层
public void transfer(String outUser,String inUser,int money){
Connection conn = null;
try{
//1获取连接
conn = JdbcUtils.getConnection();
//2开启事务
conn.setAutoCommit(false);
accountDao.outMoney(conn,outUser,money);
accountDao.outMoney(conn,outUser,money);
//3提交事务
conn.commit();
}catch(Exception e){
try{
//回滚
if(conn != null){
conn.rollback();
}catch(Exception e2){
}
throw new RuntimeException(e);
}finally{
JdbcUtils.closeResource(conn,null,null);
}
}
}
dao层
/**
* 汇款
* @param outUser 汇款人
* @param money -
*/
public void outMoney(Connection conn,String outUser,int money){
//Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try{
//1获取连接
//conn = JdbcUtils.getConnection();
//2准备sql语句
String sql = "update account set money = money - ? where username = ?";
//3预处理
psmt = conn.prepareStatement(sql);
//4设置实际参数
psmt.setInt(1,money);
psmt.setString(2,outUser);
//5执行
int r = psmt.executeUpdate();
System.out.println(r);
}catch (Exception e){
throw new RuntimeException(e);
}finally{
//6释放资源
JdbcUtils.closeResource(null,psmt,rs);
}
}
/**
* 收款
* @param inUser 收款人
* @param money +
*/
public void inMoney(Connection conn,String inUser , int money){
//Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try {
//1 获得连接
//conn = JdbcUtils.getConnection();
//2 准备sql语句
String sql = "update account set money = money + ? where username = ?";
//3预处理
psmt = conn.prepareStatement(sql);
//4设置实际参数
psmt.setInt(1, money);
psmt.setString(2, inUser);
//5执行
int r = psmt.executeUpdate();
System.out.println(r);
} catch (Exception e) {
throw new RuntimeException(e);
} finally{
//6释放资源
JdbcUtils.closeResource(null, psmt, rs);
}
}
来源:CSDN
作者:皮卡丘鹏
链接:https://blog.csdn.net/weixin_45492425/article/details/103458389