事务(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 ...
随机推荐
- jquery实现选项卡(两句即可实现)
<!DOCTYPE HTML><html> <head> <meta charset="utf-8"> ...
- mysql 记录的增删改查
MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的DML语言 ...
- Spring和Spring MVC包扫描
在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景 ...
- visual studio code 的必装推荐插件plugin, vscode, vsc
An Old Hope Theme (theme, 推荐,且推荐它的 classic theme,安装后在颜色选项里选择,该插件的定制见文末) Cobalt2 (theme) Drac ...
- 安恒X计划12月月赛
ezweb 主要是序列化问题.没有PHP环境,在线运行的.实例化对象之后修改一下file.然后echo输出序列化的结果.不过下面有一个正则检查.数字前加一个+,影响了正则的匹配,但是对于序列化的还原没 ...
- nodejs 将网上的图片下载到本地文件
var request = require('request'); var fs = require('fs'); var img_src = 'https://www.baidu.com/img/b ...
- 使用nvm管理node版本时,各个版本下公用npm安装的插件问题
因为使用了NVM(node版本管理工具),所以在切换node版本的时候安装的插件不能共享使用,必须重新安装,导致不必要的工作量 所以我将npm(node包管理工具提取出来) 进行node版本之间的共享 ...
- 第一篇 Python图片处理模块PIL(pillow)
本篇包含:一.Image类的属性:1.Format 2.Mode 3.Size 4.Palette 5.Info 二.类的函数:1.New ...
- 定位性能问题的18个linux命令
1.TopTop命令是一个性能监控程序,它按一定的顺序显示所有正在运行而且处于活动状态的实时进程,而且会定期更新显示结果.这条命令显示了CPU的使用率.内存使用率.交换内存使用大小.高速缓存使用大小. ...
- VMWare中桥接、NAT、Host-only
1.概述 2.bridged(桥接模式) 3.NAT(网络地址转换模式) 4.host-only(主机模式) 5.replicate physical network connection state ...