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.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...
随机推荐
- Android项目开发第二天,关于GitHub
一. 今天在网上学习了如何使用GitHub,了解了GitHub是干什么的. 作为开源代码库以及版本控制系统,Github拥有超过900万开发者用户.随着越来越多的应用程序转移到了云上,Github已经 ...
- 关于使用MUI框架ashx获取值的问题
前台如有 var value = '<%= value%>'; 后台在使用 Params["value"]的时候会出现重复(例:value,value).
- tomcat的jks的私钥导出nginx需要的key文件
方法一: 1.先用keytool导出pfx文件.第一个123456是jks密码,后边两个是新生成的pfx的密码 keytool -v -importkeystore -srckeystore D:\\ ...
- vim自动补全头注释与说明
做个笔记吧. .vimrc autocmd BufNewFile *.c,*.cpp,*.sh,*.py,*.java exec ":call SetTitle()" " ...
- 常用验证正则:用户名、密码、邮箱、手机号、身份证(PHP和JavaScript)
日常开发中,常常会用到一些简单常用的正则表达式,用于判断一些常见的情况 下边,就列出五种(验证用户名,密码强度,邮箱格式,手机号格式和身份证格式)常见的情况 分成PHP版本和JavaScript两个版 ...
- Bugku-CTF之点击一百万次
Day16 点击一百万次 http://123.206.87.240:9001/test/ hints:JavaScript
- [pytorch修改]npyio.py 实现在标签中使用两种delimiter分割文件的行
from __future__ import division, absolute_import, print_function import io import sys import os impo ...
- [译]RabbitMQ教程C#版 - "Hello World"
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- python学习-----协程
一.协程的引入 对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算, ...
- Codefoces 277 E. Binary Tree on Plane
题目链接:http://codeforces.com/problemset/problem/277/E 参考了这篇题解:http://blog.csdn.net/Sakai_Masato/articl ...