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. MySQL纯透明的分库分表技术还没有

    MySQL纯透明的分库分表技术还没有  种树人./oneproxy --proxy-address=:3307 --admin-username=admin --admin-password=D033 ...

  2. M2Eclipse:Maven Eclipse插件无法搜索远程库的解决方法

    使用Eclipse安装了maven插件之后,创建Maven工程,发现添加依赖“Add Dependency”的时候无法自动搜索远程库. 如果不能搜索远程库那用这个插件有啥用撒... 查遍了所有的mav ...

  3. windows下编译和安装boost库

    boost是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库. 获取方式 boost提供源码形式的安装包,可以从boost官方网站下载,目前最新版本是1.59.0. 本机上正好有boos ...

  4. python sys.path[0] 的解释

    sys.path是python的搜索模块的路径集,返回的结果是一个list path[0] 此列表的第一项,path[0],在程序启动时初始化,是包含用来调用Python解释器的脚本的目录.如果脚本目 ...

  5. MongoDB 工具助手类(.NET)

    在开发过程中,需要用到MongoDB,本身MongoDB自己对类的封装就特别好了.为了更加符合我们平时的开发使用,我现在进行了一个简单的封装操作. 连接数据库类:MongoDBContext usin ...

  6. jQuery在iframe里取得父窗口的某个元素的值

    提供一款jQuery在iframe里取得父窗口的某个元素的值实现,这个iframe用js也差不多,有需要的朋友可以参考一下. 1.在父窗口中获取指定iframe(testiframe) id 为 te ...

  7. 面经:Google两轮背靠背

    如题,谷歌两轮背靠背电面.两轮都是废话不多说直奔coding,虽然第一轮的中国大哥还是花了一点点时间了解了一下我的背景.毕业时间.research方向.说好的research面呢? 中国大哥出的题: ...

  8. #C++初学记录(算法2)

    A - Game 23 Polycarp plays "Game 23". Initially he has a number n and his goal is to trans ...

  9. 复制控件出错--提示XX控件不存在

    有时候比较喜欢复制粘贴,但是结果就是,经常出现XX控件找不到,或者不存在之类的话~~ 错误如下: 在相当郁闷的时候,尝试了一种很土土的方法,就是直接新建一个同名新页面,把前台和后台的代码复制进去~~ ...

  10. RocketMQ事务消费和顺序消费详解

    一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消费场景 在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成. ...