JDBC(9)—事务(Transaction)
数据库事务:在数据库中所谓事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态。为确保数据库中的数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这些单元中一部分操作失败,整个事务全部视为错误,所有从起始点开始以后的操作应全部回退到开始状态。
事务的操作:先定义开始一个事务,然后对数据进行修改操作,这时如果提交(commit),这些修改就永久的保存下来,
*如果回退(rollback)数据库管理系统将放弃所做的所有修改操作,而回到开始事务时的状态。事务的(ACID)属性:
——原子性(Atomicity):是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
——一致性(Consistency):事务必须使数据库从一个一致性状态转变成另外一个一致性状态。
——隔离性(Lsolation):指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的并发执行的各个事务不能相互干扰。
——持久性(Durability):指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的接下来的其他操作和数据库的故障不应该对其有任何影响。
JDBC的事务:指构成单个逻辑工作单元的操作集合。
事务处理:保证所有的事务都作为一个工作单元来执行,即使出现了故障都不能改变这种执行方式,当在一个事务中执行多个操作时要么所有的事务都被提交,要么整个事务回滚到最初的状态。
当一个连接对象被创建时默认情况下是自动提交事务,每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚,为了让多个SQL语句作为一个事务执行,可使用一下步骤:
- ——调用Connection对象的setAutoCommit(false),以取消自动提交事务。
- ——在所有的SQL语句都成功执行后,调用commit方法提交事务。
- ——在出现异常时,调用rollback方法,事务回滚。
- ——若此时Conneciton没有关闭,则需要恢复其自动提交状态。
注意:若使用的数据库引擎不是innodb,则事务无法回滚。而mysql默认的数据库引擎是MyISAM,所以第一次使用事务则需要更改数据表的引擎。
事务的隔离级别:对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
- ——脏读:对于两个事务T1、T2,T1读取的已经被T2更新但没有提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的。
- ——不可重复读:对于两个事务T1、T2,T1读取的一个字段,T2更新了该字段之后,T1再次读取同一个字段,值就不一样了。
- ——幻读:对于两个事务T1、T2,T1从表中读取一个字段,然后T2在表中插入一些行,之后T1再次读取同一张表,就会多出几行。
数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使他们不会相会影响,避免各种并发问题。
隔离级别:一个事务和其他事务隔离的程度。隔离级别越高,数据一致性就越好,但并发性越弱。
数据库提供的四种事务隔离级别。
- ——read uncommitted(读未提交数据)
- ——read committed(读已提交数据)
- ——repeatable read(可重复读)
- ——serialized(串行化)
- Oracle支持2种事务隔离级别read uncommitted、serialized,默认是read uncommitted
- Mysql支持4种隔离级别,默认repeatable read。
- 设置事务隔离级别:
- 使用sql语句:select @@tx_isolation查看当前隔离级别
- ——设置当前的mysql连接的隔离级别:set transaction isolation level read commited;
- ——设置数据库系统的全局隔离级别:set global transaction isolation level read commited;
- 使用代码:
conn.setTransactionIsolation(conn.TRANSACTION_READ_COMMITTED);
代码实例
public class Transaction_10 {
/**
* 1.Tom给Jerry汇款500元
*注意:如果多个操作,每个操作使用的都是自己单独的连接,则无法保证事务。
*/
@Test
public void testTransaction(){
DAO1_7 dao = new DAO1_7();
String sql = "update user set balance = balance - 500 where id = 1";
dao.update(sql);
//出现异常时,Tom的钱被扣掉500,但是Jerry的钱没有增加500,
int number = 10 / 0;
System.out.println(number);
sql = "update user set balance = balance + 500 where id = 2";
dao.update(sql);
}
/**
* 2.修改以上(1)方法,使用同一个连接
* @param conn
* @param sql
* @param objects
*/
public void update(Connection conn, String sql, Object ...objects){
PreparedStatement preparedstatement = null;
try {
preparedstatement = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
preparedstatement.setObject(i + 1, objects[i]);
}
preparedstatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(preparedstatement,null);
}
}
/**
* 2_1.测试以上方法
*/
@Test
public void test(){
Connection conn = null;
try {
conn = TestTools.getConnection();
//开始事务,在开始之前要关闭数据库默认自动提交
conn.setAutoCommit(false);
String sql = "update users set balance = balance - 500 where id = 1";
update(conn,sql);
//出现异常时,事务回滚到之前的状态
int number = 10 / 0;
System.out.println(number);
sql = "update users set balance = balance + 500 where id = 2";
update(conn,sql);
//结束,就提交事务
conn.commit();
} catch (Exception e) {
e.printStackTrace();
//发生异常,事务回滚
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
//设置事务提交方式为自动提交:
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
//关闭连接
TestTools.release(null, conn);
}
}
/**
* 3.返回某条记录的某一个字段的值或一个统计的值(一共有多少条记录等。),即:确定的某一行的某个字段的值,
*或者计算的值,3.、3_1.方法处理数据并设置隔离级别,3_2.方法获取数据以测试不同的隔离级别下获取的数据的差异
* @param sql
* @param objects
* @return
*/
public <E> E getForValue(String sql, Object ... objects){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.得到结果集:该结果集应该只有一行,且只有一列
conn = TestTools.getConnection();
//设置隔离级别:读未提交,该隔离级别即使事务未提交也可获得更新但未提交的的数据。获取数据结果:500
//conn.setTransactionIsolation(conn.TRANSACTION_READ_UNCOMMITTED);
//设置隔离级别:读已提交,该隔离级别若事务未提交则获取更新之前的数据,获取数据结果:1000
conn.setTransactionIsolation(conn.TRANSACTION_READ_COMMITTED);
ps = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
ps.setObject(i + 1, objects[i]);
}
rs = ps.executeQuery();
if(rs.next()){
//2.取得结果
return (E)rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, ps, conn);
}
return null;
}
/**
* 3_1.测试以上方法设置事务的隔离级别,使用update方法更新数据,使balance数据减500
*/
@Test
public void testTransactionIsolationUpdate(){
Connection conn = null;
try {
conn = TestTools.getConnection();
//关闭自动提交
conn.setAutoCommit(false);
String sql = "update users set balance = balance - 500 where id = 1";
update(conn, sql);
//提交事务
conn.commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(null, conn);
}
}
/**
* 3_2.使用getForValue()方法,查询被更新但未提交的数据
*/
@Test
public void testTransactionIosationRead(){
String sql = "select balance from users where id = 1";
Integer balance = getForValue(sql);
System.out.println(balance);
}
}
JDBC(9)—事务(Transaction)的更多相关文章
- jdbc、事务(Transaction)、批处理 回顾
论文写的头疼,回顾一下jdbc,换换脑子 传统的写法: 1.加载驱动类 class.forname("jdbc类的包结构"); 2.获得连接 Connection conn=Dri ...
- JDBC中的事务-Transaction
事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...
- MySql事务及JDBC对事务的使用
一 .事务的几个重要特性 1. 原子性 事务内的每个内容不可分割,是一个统一的整体.或同时进行或同时消亡. 2.一致性 事务执行前和事务执行后,状态都是统一的.如A转B 100元,A和B数据总额度没有 ...
- JDBC 之 事务
1.概念:事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功. 2.数据库开启事务的命令dtl: Start transaction开启事务 Rollback回滚事务(撤销) ...
- 事务之使用JDBC进行事务的操作2
本篇将讲诉如何使用JDBC进行数据库有关事务的操作.在上一篇博客中已经介绍了事务的概念,和在MySQL命令行窗口进行开启事务,提交事务以及回滚事务的操作. 似乎事务和批处理都可以一次同时执行多条SQL ...
- JDBC控制事务
概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并 ...
- JDBC处理事务
一.什么是事务? 在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务! 二.事务是必须满足4个条件(AC ...
- springboot成神之——spring boot,spring jdbc和spring transaction的使用
本文介绍spring boot,spring jdbc和spring transaction的使用 项目结构 依赖 application model层 mapper层 dao层 exception层 ...
- Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...
1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback 回滚事务 •Commit ...
- day18-事务与连接池 3.jdbc中事务操作介绍
那么我们都是通过程序操作数据库.所以要了解jdbc下怎样对事务操作.jdbc如何操作事务? 自动事务false那就不开了呗相当于开启事务. package cn.itcast.transaction; ...
随机推荐
- 调整LaTeX文档页面的大小
看下面这张图片便一目了然!!! 借助 geometry 包,可以很方便地调整页面大小,常用的参数如图所示,这些参数都可以通过LateX支持的单位(mm, cm, pt, in)去重新设置. ...
- Vue axios 返回数据绑定到vue对象问题
在项目中需要用到后台的数据对前端渲染,使用到了vue整合的axios,使用vue中的钩子函数在页面组件挂载完成之后向后台发送一个get请求然后将返回后的数据赋值data()中定义的属性: 执行后前端报 ...
- Python学习(二十九)—— pymysql操作数据库优化
转载自:http://www.cnblogs.com/liwenzhou/articles/8283687.html 我们之前使用pymysql操作数据库的操作都是写死在视图函数中的,并且很多都是重复 ...
- Python学习(十九) —— 前端基础之HTML
转载自:http://www.cnblogs.com/liwenzhou/p/7988087.html 一.HTML介绍 1.Web服务本质 import socket sk = socket.soc ...
- maven私服nexus(三)
将项目中的第三方jar包上传至maven私服中 上传jar包到maven私服 在你使用的maven配置文件settings中加上如下信息 代表你访问的账号密码 <servers> < ...
- nginx安装,运行(ubuntu)
文本只涉及单节点nginx 安装gcc g++依赖库 apt-get install build-essential apt-get install libtool 安装pcre依赖库 apt-get ...
- OpenJ_Bailian 4017 爬楼梯
时间限制: 1000 ms 空间限制: 262144 KB 题目描述 树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数.例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一 ...
- MATLAB的一些使用的快捷键整理
1.用TAB键可以实现缩进,怎么缩进和取消缩进呢? 在使用脚本编写matlab的程序时,我们通过选中需要的程序,按下tab键就能缩进整个程序.同样的,当我们需要取消缩进时,我们的快捷方法就是:shif ...
- GYM 101755 K.Video Reviews 【贪心】+【二分】
<题目链接> 题目大意: 一家公司想让n个人给他们的产品评论,所以依次去找这n个人,第i个人会评论当且仅当已经有ai个人评论或他确实对这个产品感兴趣,但是这n个人都不对这个产品感兴趣,问这 ...
- Callable与Runable接口 submit与execute区别
execute(Runnable x) 没有返回值.可以执行任务,但无法判断任务是否成功完成. submit(Runnable x) 返回一个future.可以用这个future来判断任务是否成功完成 ...