在之前的学习中,我们学习了使用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事物)的更多相关文章

  1. 【初学Java学习笔记】SQL语句调优

    1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认 ...

  2. Java学习笔记39(转换流)

    转换流:字符流和字节流之间的桥梁 用于处理程序的编码问题 OutputStreamWriter类:字符转字节流 写文本文件: package demo; import java.io.FileOutp ...

  3. 【转】JAVA学习笔记----PL/SQL最差实践

    1. 超长的PL/SQL代码   影响:可维护性,性能   症状:    在复杂的企业应用中,存在动辄成百上千行的存储过程或上万行的包.为什么是最差:    太长的PL/SQL代码不利于阅读,第三方工 ...

  4. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  5. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  6. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  7. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  8. 20145330第九周《Java学习笔记》

    20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...

  9. Java学习笔记心得——初识Java

    初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...

随机推荐

  1. 记账本微信小程序开发四

    学习添加组件 集成日期组件 添加组件 需要在main.js文件中,声明一个data值date与wxml中的{{date}}绑定关联,然后在onLoad中初始化字符串格式的日期值, 处理日期组件点击确认 ...

  2. Java内存模型学习笔记

    Java内存模型(JMM):描述了java程序中各种变量(线程共享变量)的范根规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节.共享变量就是指一个线程中的变量在其他线程中也是可见 ...

  3. WSDL文档结构图

  4. Solr和Lucene的区别?

    1.Lucene 是工具包 是jar包 2.Solr是索引引擎服务  War 3.Solr是基于Lucene(底层是由Lucene写的) 4.上面二个软件都是Apache公司由java写的 5.Luc ...

  5. centos7.3配置python2、3环境与配置各自pip

    环境:CentOS-7-x86_64-Everything-1611 No.1 查看CentOS对Python的默认依赖 [root@cs ~]# ls /usr/bin/python* /usr/b ...

  6. opencv学习之路(31)、GrabCut & FloodFill图像分割

    一.GrabCut 1.利用Rect做分割 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat ...

  7. css实现横向进度条和竖向进度条

    一.横向进度条 <html> <head> <title>横向进度条</title> <style type="text/css&quo ...

  8. 同事在使用shiro后遇到的异常

    一切配置按照demo来的,给他讲了一遍捋顺了.然后之前他做的demohim按照他网络摘抄的shiro博客看的. 然后注册了,正常,登录,提示密码不匹配. 问题出在注册的密码加密次数是2, 而shiro ...

  9. 马上AI全球挑战者大赛-违约用户风险预测

    方案概述 近年来,互联网金融已经是当今社会上的一个金融发展趋势.在金融领域,无论是投资理财还是借贷放款,风险控制永远是业务的核心基础.对于消费金融来说,其主要服务对象的特点是:额度小.人群大.周期短, ...

  10. idea maven列表有问题的

     idea maven列表有问题的,覆盖   C:\Users\用户名\.IntelliJIdea2017.2\system\Maven\Indices路径大致在这里  文件为 Indices.rar ...