1、演示转账的功能:
(1)创建一张表示学生表表
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
account DECIMAL(11,2)

)

(2)向表中插入几个用户
INSERT INTO student(id,name,account ) VALUES(NULL,'stu1',1000);
INSERT INTO student(id,name,account ) VALUES(NULL,'stu2',1000);
SELECT * FROM student;

(3)stu1向stu2转账100元
从stu1的账号减去100元
UPDATE student SET account = account - 100 WHERE name='stu1';

#给shaheshang的账号加上100元
UPDATE student SET account = account +100 WHERE name = 'stu2';

重新设置为1000元:
UPDATE student SET account =1000;

2、用代码演示上述过程

 //StudentDao类
public static int updateAge(Connection conn,Integer id,Integer account) {
Connection conn = null;
PreparedStatement ps = null;
String sql = "update student set account=account+? where id=?";
int i = 0;
try {
conn = DBUtil.getConn();
ps = conn.prepareStatement(sql);
ps.setInt(1, account);
ps.setInt(2, id);
i = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally{
DBUtil.close(conn, ps, null);
}
return i;
}
//测试类
@Test
public void testTransaction() {
try {
StudentDao.updateAccount(conn, 1, -100);
//int i=10/0;
StudentDao.updateAccount(conn, 2, 100);
} catch (SQLException e) {
e.printStackTrace();
}
}

正常执行,没有问题,但是若将 int i=10/0; 处的注解放开,则id为1的账户减少100元,id为2的账户并没有增加100元,银行赚了。

3、用事务的方式解决上述问题

事务(Transaction)

  • 事务的特性(ACID):

    • 原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
    • 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
    • 隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
    • 持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
  • 操作事务的基本步骤:
    • 开启事务:开启事务以后,我们以后的所有操作将都会在同一个事务当中
    • 操作数据库:开启事务以后再去操作数据库,所有操作将不会直接提交到数据库中
    • 提交事务:将修改应用到数据库
    • 回滚事务:数据库操作过程中出现异常了,回滚事务,回滚事务以后,数据库变成开启事务之前的状态
  • mysql中的事务控制
    • 开启事务:START TRANSACTION
    • 提交事务:COMMIT
    • 回滚事务:ROLLBACK
  • JDBC中的事务主要通过Connection对象来控制的
    • 开启事务

      • void setAutoCommit(boolean autoCommit) throws SQLException;
      • //设置事务是否自动提交,默认是自动提交
      • //设置事务手动提交
      • conn.setAutoCommit(false);
    • //提交事务
      • void commit() throws SQLException;
      • //提交事务
      • conn.commit()
    • 回滚事务
      • void rollback() throws SQLException;
      • //回滚事务
      • conn.rollback()
  • 事务控制的格式:
 Connection conn = null;//创建一个Connection
try{
conn = JDBCUtils.getConnection();//获取Connection
conn.setAutoCommit(false);//开启事务
//对数据库进行操作
conn.commit();//操作成功,提交事务
} catch(Exception e){
e.printStackTrace();
//回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally{
DBUtil.close(conn, null, null);
}

注意:在同一个事务中使用的数据库连接(Connection)必须是同一个,否则事务不起作用!

对上面的代码进行修改

 //StudentDao类
public static int updateAccount(Connection conn,Integer id,Integer account) {
PreparedStatement ps = null;
String sql = "update student set account=account+? where id=?";
int i = 0;
try {
ps = conn.prepareStatement(sql);
ps.setInt(1, account);
ps.setInt(2, id);
i = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally{
DBUtil.close(null, ps, null);
}
return i;
}
//测试类
@Test
public void testTransaction() {
Connection conn = DBUtil.getConn();//获取连接Connection
try {
conn.setAutoCommit(false);//开启事务
StudentDao.updateAccount(conn, 1, -100);
int i=10/0;
StudentDao.updateAccount(conn, 2, 100);
conn.commit();//操作成功,提交事务
} catch (SQLException e) {
e.printStackTrace();
//回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally{
DBUtil.close(conn, null, null);
}
}

int i=10/0; 处抛出了错误,但是事务没有提交,并进行了回滚,所以数据库中的数据没有变,运行正常的话,可以进行正常转账。

4、批处理和事务的结合

实际开发中,批处理和事务常常是结合在一起使用。速度会成倍增加

 @Test
public void testTransBatch() {
Connection conn = DBUtil.getConn();
PreparedStatement ps = null;
try {
conn.setAutoCommit(false);//开启事务
String sql = "INSERT INTO student(NAME) VALUES(?)";
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < 1000; i++) {
ps.setString(1, "stu"+i);
ps.addBatch();
}
long start = System.currentTimeMillis();
ps.executeBatch();
long end = System.currentTimeMillis();
System.out.println((end-start)+"ms");
} catch (SQLException e) {
e.printStackTrace();
}
conn.commit();//提交事务
} catch (SQLException e) {
//回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally{
DBUtil.close(conn, ps, null);
}
}

运行时间:平均20ms左右

sql批处理(batch)的简单使用

DBUtil工具类--->资源目录--->工具类--->数据库操作工具类

事务(Transaction)的更多相关文章

  1. SQL Server 数据库的维护(三)__事务(transaction)和锁

    --维护数据库-- --事务(transaction)和锁-- --事务(transaction)-- --概述: 事务是指封装了一组T-SQL语句的单个逻辑单元.单元中的所有语句作为一个整体,在满足 ...

  2. JDBC中的事务-Transaction

    事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...

  3. Spring事务Transaction配置的五种注入方式详解

    Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...

  4. SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

    假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...

  5. FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)

    用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...

  6. 事务(Transaction)概念和特性

    http://baike.baidu.com/view/121511.htm 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库 ...

  7. redis源码分析之事务Transaction(下)

    接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...

  8. 数据库事务(Transaction)

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...

  9. 事务Transaction

    目录 为什么写这系列的文章 事务概念 ACID 并发事务导致的问题 脏读(Dirty Read) 非重复读(Nonrepeatable Read) 幻读(Phantom Reads) 丢失修改(Los ...

  10. jdbc、事务(Transaction)、批处理 回顾

    论文写的头疼,回顾一下jdbc,换换脑子 传统的写法: 1.加载驱动类 class.forname("jdbc类的包结构"); 2.获得连接 Connection conn=Dri ...

随机推荐

  1. html 1:1比例显示

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale= ...

  2. 创建list方法总结

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sheismylife/article/details/28878593 构建一个list 注意要标记 ...

  3. 如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件

    copy内容的网址: https://segmentfault.com/a/1190000007020623 使用vue-cli构建的vue项目,webpack的配置文件是分散在很多地方的,而我们需要 ...

  4. POD类型

    POD类型 POD全称Plain Old Data.通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型. C++11将POD划分为两个基本概念的合集,即:平凡的和标准 ...

  5. [vue]vue-book

    我们打算要做这几个模块 首页 列表 收藏 添加 home.vue --> list.vue -->app.vue --> main.js 安装环境 npm i vue-cli -g ...

  6. Amazon SES SPF和DKIM设置教程

    SPF和DKIM设置是争对域名邮箱而言的(公共邮件也不会给你修改DNS的权限),主要作用就是防止邮箱伪造提升邮件信用度 首先到亚马逊添加域名并验证 添加后,给出了域名验证的方法,就是在dns记录里添加 ...

  7. VMware coding Challenge:Date of Weekday

    这道题再次证明了这种细节的题目,画个图容易搞清楚 import java.util.Scanner; public class Solution2 { static int DateOfWeekday ...

  8. JS参差不齐的数组

    <html><head> <title>参差不齐的数组</title> <meta charset="utf-8"> & ...

  9. 网络编程—代码—UDP数据报传输

    UDP:数据报传输 1.接收端 public class Udps { //接收端 public static void main(String[] args) throws IOException ...

  10. hdu 6201 transaction transaction transaction

    https://vjudge.net/contest/184514#problem/H 题意: 一个商人为了赚钱,在城市之间倒卖商品.有n个城市,每个城市之间有且只有一条无向边连通.给出n个城市的货物 ...