java学习笔记39(sql事物)
在之前的学习中,我们学习了使用PreparedStatement类,使用这个类消除了sql注入的隐患,可是,还有些一些其他的隐患,这里以银行转账业务为例,
假设 一个银行,张三在里面存了1000元,李四也在里面存了1000元,张三给李四转账500,那么张三的钱少500,李四的钱多500,可是如果转账的瞬间,张三的钱扣过后,给李四增加钱之前,假设停电了,那么钱就不见了,具体如下:
创建一个假设银行的数据表:
create table account
(
id int auto_increment
primary key,
NAME varchar(10) null,
balnce double null
);
当张三给李四转账500元时,我们用两句语句分开执行,java实现具体代码如下:
package com.zs.Demo; import JDBCUtils.JDBCUtils; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner; public class ZhuanZhang {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入转账金额:");
double money = sc.nextDouble();
zhuanzhang(money);
} private static void zhuanzhang(double money) {
Connection conn = JDBCUtils.getConnection();
PreparedStatement pre=null;
try {
//张三减少money元
String sql = "update account set balnce = balnce-? where name=?;";
pre = conn.prepareStatement(sql);
pre.setDouble(1,money);
pre.setString(2,"张三");
pre.executeUpdate();
//李四增加money元
String sql2="update account set balnce = balnce+? where name=?;";
pre = conn.prepareStatement(sql2);
pre.setDouble(1, money);
pre.setString(2,"李四");
pre.executeUpdate();
System.out.println("转账成功");
} catch (SQLException e) {
System.out.println("转账失败");
e.printStackTrace();
}finally{
JDBCUtils.close(conn,pre);
}
}
}
运行结果:
我们现在在张三和李四转账之间插入一个异常,假设停电,具体代码在上面代码中添加一句异常,如下:
package com.zs.Demo; import JDBCUtils.JDBCUtils; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner; public class ZhuanZhang {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入转账金额:");
double money = sc.nextDouble();
zhuanzhang(money);
} private static void zhuanzhang(double money) {
Connection conn = JDBCUtils.getConnection();
PreparedStatement pre=null;
try {
//张三减少money元
String sql = "update account set balnce = balnce-? where name=?;";
pre = conn.prepareStatement(sql);
pre.setDouble(1,money);
pre.setString(2,"张三");
pre.executeUpdate();
/*这里插入异常,0不能作为除数,所以这里会报错,用这种方式来假设停电之类的异常,我们会发现上
面的语句已经执行了,到这里出现异常下面的语句不能执行,张三的钱扣了,李四的钱却没有增加,钱不见了*/
System.out.println(100/0); //李四增加money元
String sql2="update account set balnce = balnce+? where name=?;";
pre = conn.prepareStatement(sql2);
pre.setDouble(1, money);
pre.setString(2,"李四");
pre.executeUpdate();
System.out.println("转账成功");
} catch (SQLException e) {
System.out.println("转账失败");
e.printStackTrace();
}finally{
JDBCUtils.close(conn,pre);
}
}
}
运行结果:
这时我们发现钱少了500,不见了,为了解决这种问题,数据库中,我们把这两种操作捆绑成一个事物,执行结果有两种,成功或者失败,不可以分开执行,
执行成功称为:提交事务,出现异常或者失败称:回滚事务。
在该例种,我们使用事物来处理时,思路如下:
1.获取链接
2.开启事物
3.获取PreparedStatement对象
4.执行两次更新操作,
5.正常情况提交事务,出现异常时回滚事物
6.关闭资源
代码:
package com.zs.Demo; import JDBCUtils.JDBCUtils; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner; /*需求分析:模拟银行转账业务,张三给李四转账,当张三的钱扣除后,李四的钱增加*/
public class ShiWu {
private static PreparedStatement pre;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入转账金额:");
double money = sc.nextDouble();
zhuangzhang(money);
} private static void zhuangzhang(double money) {
//获得连接
Connection conn=JDBCUtils.getConnection();
try {
// 开启事物功能
conn.setAutoCommit(false);
// 执行sql语句
String sql="update account set balnce=balnce-? where name=?";
String sql2="update account set balnce = balnce+? where name=?";
pre= conn.prepareStatement(sql);
pre.setDouble(1,money);
pre.setString(2,"张三");
/*这里添加异常,到这里时出现异常,所以事物不成功,回滚事物,去掉下面异常语句,程序正常提交事务*/
System.out.println(100/0); pre.executeUpdate();
pre= conn.prepareStatement(sql2);
pre.setDouble(1,money);
pre.setString(2,"李四");
pre.executeUpdate();
// 提交事务
conn.commit();
System.out.println("转账成功");
} catch (Exception e) {
try {
// 回滚事务
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
System.out.println("转账失败");
}
// 关闭资源
JDBCUtils.close(conn,pre);
}
}
运行结果:
正常提交的话,将代码中的异常语句注销就可以了,出现异常时,就会回滚事务,我们发现钱没有少,整个事务执行失败,异常前面的代码也没有成功执行。
java学习笔记39(sql事物)的更多相关文章
- 【初学Java学习笔记】SQL语句调优
1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认 ...
- Java学习笔记39(转换流)
转换流:字符流和字节流之间的桥梁 用于处理程序的编码问题 OutputStreamWriter类:字符转字节流 写文本文件: package demo; import java.io.FileOutp ...
- 【转】JAVA学习笔记----PL/SQL最差实践
1. 超长的PL/SQL代码 影响:可维护性,性能 症状: 在复杂的企业应用中,存在动辄成百上千行的存储过程或上万行的包.为什么是最差: 太长的PL/SQL代码不利于阅读,第三方工 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- Java学习笔记(04)
Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 20145330第九周《Java学习笔记》
20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...
- Java学习笔记心得——初识Java
初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...
随机推荐
- 创建servlet程序知识点详解---servlet-day12
自定义标签 (1)编程步骤 step1 jsp标签分为复杂标签技术(old),简单标签(new) 注(了解) jsp标签技术分为复杂标签技术(old),简单标签技术(new) step2 ###MVC ...
- MySQL中group by , sum , case when then 的使用
在我们使用数据库的时候,可能会遇到需要进行统计的情况. 比如需要统计一下,下表中各个年份的胜负场数. 遇到这样的情况,我们应该怎么办呢? 在mysql中我们可以使用group by sum case ...
- Vue 组件&组件之间的通信 之 template模板引用与动态组件的使用
template模板引用 在component的template中书写大量的HTML元素很麻烦. Vue提供了<template>标签,可以在里边书写HTML,然后通过ID指定到组建内的t ...
- Python爬虫(四)——开封市58同城数据模型训练与检测
前文参考: Python爬虫(一)——开封市58同城租房信息 Python爬虫(二)——对开封市58同城出租房数据进行分析 Python爬虫(三)——对豆瓣图书各模块评论数与评分图形化分析 数据的构建 ...
- Log4j配置记录
log4j的配置文件就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境. 1.配置文件 log4j配置文件的基 ...
- topcoder srm 580 div1
problem1 link 最优选择一定是在$2n$个端点中选出两个. problem2 link 分开考虑每个区间.设所有区间的左端点的最大值为$lc$,所有区间的右端点的最小值为$rc$.对于某个 ...
- topcoder srm 560 div1
problem1 link 从大到小贪心,较大的数字应该放置在较浅的位置. problem2 link 最后的位置要么都是整数(经过偶数次变换),要么是$(p.5, q.5)$这种位置(奇数次变换). ...
- P4726 【模板】多项式指数函数
思路 按照式子计算即可 \[ F(x)=F_0(x)(1-\ln F_0(x) +A(x)) \] 代码 // luogu-judger-enable-o2 #include <cstdio&g ...
- (转) Ensemble Methods for Deep Learning Neural Networks to Reduce Variance and Improve Performance
Ensemble Methods for Deep Learning Neural Networks to Reduce Variance and Improve Performance 2018-1 ...
- LINQ之路11:LINQ Operators之过滤(Filtering)
在本系列博客前面的篇章中,已经对LINQ的作用.C# 3.0为LINQ提供的新特性,还有几种典型的LINQ技术:LINQ to Objects.LINQ to SQL.Entity Framework ...