事务(Transaction)
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、用代码演示上述过程
1 //StudentDao类 2 public static int updateAge(Connection conn,Integer id,Integer account) { 3 Connection conn = null; 4 PreparedStatement ps = null; 5 String sql = "update student set account=account+? where id=?"; 6 int i = 0; 7 try { 8 conn = DBUtil.getConn(); 9 ps = conn.prepareStatement(sql); 10 ps.setInt(1, account); 11 ps.setInt(2, id); 12 i = ps.executeUpdate(); 13 } catch (SQLException e) { 14 e.printStackTrace(); 15 } finally{ 16 DBUtil.close(conn, ps, null); 17 } 18 return i; 19 } 20 //测试类 21 @Test 22 public void testTransaction() { 23 try { 24 StudentDao.updateAccount(conn, 1, -100); 25 //int i=10/0; 26 StudentDao.updateAccount(conn, 2, 100); 27 } catch (SQLException e) { 28 e.printStackTrace(); 29 } 30 }
正常执行,没有问题,但是若将 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()
- 开启事务
- 事务控制的格式:
1 Connection conn = null;//创建一个Connection 2 try{ 3 conn = JDBCUtils.getConnection();//获取Connection 4 conn.setAutoCommit(false);//开启事务 5 //对数据库进行操作 6 conn.commit();//操作成功,提交事务 7 } catch(Exception e){ 8 e.printStackTrace(); 9 //回滚事务 10 try { 11 conn.rollback(); 12 } catch (SQLException e1) { 13 e1.printStackTrace(); 14 } 15 } finally{ 16 DBUtil.close(conn, null, null); 17 }
注意:在同一个事务中使用的数据库连接(Connection)必须是同一个,否则事务不起作用!
对上面的代码进行修改
1 //StudentDao类 2 public static int updateAccount(Connection conn,Integer id,Integer account) { 3 PreparedStatement ps = null; 4 String sql = "update student set account=account+? where id=?"; 5 int i = 0; 6 try { 7 ps = conn.prepareStatement(sql); 8 ps.setInt(1, account); 9 ps.setInt(2, id); 10 i = ps.executeUpdate(); 11 } catch (SQLException e) { 12 e.printStackTrace(); 13 } finally{ 14 DBUtil.close(null, ps, null); 15 } 16 return i; 17 } 18 //测试类 19 @Test 20 public void testTransaction() { 21 Connection conn = DBUtil.getConn();//获取连接Connection 22 try { 23 conn.setAutoCommit(false);//开启事务 24 StudentDao.updateAccount(conn, 1, -100); 25 int i=10/0; 26 StudentDao.updateAccount(conn, 2, 100); 27 conn.commit();//操作成功,提交事务 28 } catch (SQLException e) { 29 e.printStackTrace(); 30 //回滚事务 31 try { 32 conn.rollback(); 33 } catch (SQLException e1) { 34 e1.printStackTrace(); 35 } 36 } finally{ 37 DBUtil.close(conn, null, null); 38 } 39 }
int i=10/0; 处抛出了错误,但是事务没有提交,并进行了回滚,所以数据库中的数据没有变,运行正常的话,可以进行正常转账。
4、批处理和事务的结合
实际开发中,批处理和事务常常是结合在一起使用。速度会成倍增加
1 @Test 2 public void testTransBatch() { 3 Connection conn = DBUtil.getConn(); 4 PreparedStatement ps = null; 5 try { 6 conn.setAutoCommit(false);//开启事务 7 String sql = "INSERT INTO student(NAME) VALUES(?)"; 8 try { 9 ps = conn.prepareStatement(sql); 10 for (int i = 0; i < 1000; i++) { 11 ps.setString(1, "stu"+i); 12 ps.addBatch(); 13 } 14 long start = System.currentTimeMillis(); 15 ps.executeBatch(); 16 long end = System.currentTimeMillis(); 17 System.out.println((end-start)+"ms"); 18 } catch (SQLException e) { 19 e.printStackTrace(); 20 } 21 conn.commit();//提交事务 22 } catch (SQLException e) { 23 //回滚事务 24 try { 25 conn.rollback(); 26 } catch (SQLException e1) { 27 e1.printStackTrace(); 28 } 29 e.printStackTrace(); 30 } finally{ 31 DBUtil.close(conn, ps, null); 32 } 33 }
运行时间:平均20ms左右
sql批处理(batch)的简单使用
DBUtil工具类--->资源目录--->工具类--->数据库操作工具类
转载于:https://www.cnblogs.com/lixiang1993/p/7453809.html
事务(Transaction)相关推荐
- FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)
用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...
- 化零为整WCF(14) - 事务(Transaction)
[索引页] [源码下载] 化零为整WCF(14) - 事务(Transaction) 作者:webabcd 介绍 WCF(Windows Communication Foundation) - 事务( ...
- 什么是事务(Transaction)
摘要:事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元.事务通常由高级数据库操纵语言或编程语言书写的用户程序的执行所引起,并用形如begin transaction和 ...
- MySQL事务(transaction) (有这篇就足够了..)
MySQL事务处理(TransAction) 大家好,我是胡亦,一名热爱分享技术干货的博主. 思考了很久,决定写一篇关于mysql事务(transaction)的博客,一来嘛,因为最近在复习mysql ...
- Oracle 存储过程 中如何使用事务Transaction 自主事务 自治事务
Oracle基础 存储过程和事务 一.事务和存储过程 在存储过程中如何使用事务.当需要在存储过程中同时执行多条添加.修改.删除SQL语句时,为了保证数据完整性,我们需要使用事务.使用方式和在PL-SQ ...
- 数据库事务(Transaction)的ACID特性解释
事务(Transaction)是并发控制的基本单位.所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两 ...
- redis 在 php 中的应用(事务 [ Transaction ] 篇)
本文为我阅读了 redis参考手册 之后编写,注意 php_redis 和 redis-cli 的区别(主要是返回值类型和参数用法) 目录: Transaction(事务) WATCH UNWATCH ...
- python django事务transaction源码分析
2019独角兽企业重金招聘Python工程师标准>>> python Django事务 网上关于django1.6的事务资料很多,但是1.8的却搜不到任何资料,自己要用的时候费了不少 ...
- spring事务(Transaction)的七种事务传播行为及五种隔离级别
1. 首先,说说什么事务(Transaction) 事务,就是一组操作数据库的动作集合.事务是现代数据库理论中的核心概念之一. 如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事 ...
- Spring事务 Transaction rolled back because it has been marked as rollback-only
前言 使用Spring事务时,出现异常:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled ...
最新文章
- shell实例第11讲:取出系统IP地址,并判断属于哪个网段
- 【视频编解码:新标准 新应用】未来可期
- codeforces71A-C语言解题报告
- 太辛苦的钱,我建议不要挣
- linux vim配置缩减,让VIM更好的工作——VIM基本配置
- Oracle 19c和20c新特性最全解密
- net start mysql服务没有响应控制功能_新服务安装
- 根据类名找jar包findjar.com
- EntityFramework6.X 之 Operation
- Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
- 反向传播神经网络(Back propagation neural network ,BPNN)
- 惯性系统常用坐标系_惯性技术常用坐标系
- GTX高速收发器Transceiver之发射端Transmitter(UG476)
- PointConv:基于3D点云的深度卷积网络
- 读取iCloud vCard.vcf文件联系人
- Cisco交换机产品线和主要产品--- 型号说明
- 电脑主板深度睡眠设置
- MPLS中的标签信息库LIB和标签转发信息库LFIB + RIB/FIB + ARP/FDB + CAM/TCAM
- Bash 中的字符串变量
- 大数据(一) --大数据概述
热门文章
- react不同环境不同配置angular_DevOps 前端项目(angular、vue、react)打包静态资源生成一份Docker镜像支持部署不同环境...
- 网络品牌推广浅析网站标题该如何进行SEO优化?
- 网站SEO优化技巧的“减法运算”
- kafka消费者如何读同一生产者消息_Kafka消费者生产者实例
- java foreach用法_Java十大简单性能优化
- (转载)网络抓包原理及常用抓包工具
- jira 8.2.1 安装 及一些常见的坑
- git 回退版本并强制提交
- 高级软件工程第七次作业:东理三剑客团队作业-随笔6
- 修改与删除@property封装的数据属性