事务(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、用代码演示上述过程
//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左右
DBUtil工具类--->资源目录--->工具类--->数据库操作工具类
事务(Transaction)的更多相关文章
- SQL Server 数据库的维护(三)__事务(transaction)和锁
--维护数据库-- --事务(transaction)和锁-- --事务(transaction)-- --概述: 事务是指封装了一组T-SQL语句的单个逻辑单元.单元中的所有语句作为一个整体,在满足 ...
- JDBC中的事务-Transaction
事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...
- Spring事务Transaction配置的五种注入方式详解
Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...
- SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交
假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...
- FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)
用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...
- 事务(Transaction)概念和特性
http://baike.baidu.com/view/121511.htm 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库 ...
- redis源码分析之事务Transaction(下)
接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...
- 数据库事务(Transaction)
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...
- 事务Transaction
目录 为什么写这系列的文章 事务概念 ACID 并发事务导致的问题 脏读(Dirty Read) 非重复读(Nonrepeatable Read) 幻读(Phantom Reads) 丢失修改(Los ...
- jdbc、事务(Transaction)、批处理 回顾
论文写的头疼,回顾一下jdbc,换换脑子 传统的写法: 1.加载驱动类 class.forname("jdbc类的包结构"); 2.获得连接 Connection conn=Dri ...
随机推荐
- MySQL纯透明的分库分表技术还没有
MySQL纯透明的分库分表技术还没有 种树人./oneproxy --proxy-address=:3307 --admin-username=admin --admin-password=D033 ...
- M2Eclipse:Maven Eclipse插件无法搜索远程库的解决方法
使用Eclipse安装了maven插件之后,创建Maven工程,发现添加依赖“Add Dependency”的时候无法自动搜索远程库. 如果不能搜索远程库那用这个插件有啥用撒... 查遍了所有的mav ...
- windows下编译和安装boost库
boost是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库. 获取方式 boost提供源码形式的安装包,可以从boost官方网站下载,目前最新版本是1.59.0. 本机上正好有boos ...
- python sys.path[0] 的解释
sys.path是python的搜索模块的路径集,返回的结果是一个list path[0] 此列表的第一项,path[0],在程序启动时初始化,是包含用来调用Python解释器的脚本的目录.如果脚本目 ...
- MongoDB 工具助手类(.NET)
在开发过程中,需要用到MongoDB,本身MongoDB自己对类的封装就特别好了.为了更加符合我们平时的开发使用,我现在进行了一个简单的封装操作. 连接数据库类:MongoDBContext usin ...
- jQuery在iframe里取得父窗口的某个元素的值
提供一款jQuery在iframe里取得父窗口的某个元素的值实现,这个iframe用js也差不多,有需要的朋友可以参考一下. 1.在父窗口中获取指定iframe(testiframe) id 为 te ...
- 面经:Google两轮背靠背
如题,谷歌两轮背靠背电面.两轮都是废话不多说直奔coding,虽然第一轮的中国大哥还是花了一点点时间了解了一下我的背景.毕业时间.research方向.说好的research面呢? 中国大哥出的题: ...
- #C++初学记录(算法2)
A - Game 23 Polycarp plays "Game 23". Initially he has a number n and his goal is to trans ...
- 复制控件出错--提示XX控件不存在
有时候比较喜欢复制粘贴,但是结果就是,经常出现XX控件找不到,或者不存在之类的话~~ 错误如下: 在相当郁闷的时候,尝试了一种很土土的方法,就是直接新建一个同名新页面,把前台和后台的代码复制进去~~ ...
- RocketMQ事务消费和顺序消费详解
一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消费场景 在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成. ...