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; ...
随机推荐
- (3).NET CORE微服务 Micro-Service ---- Consul服务治理
Consul是注册中心,服务提供者.服务提供者.服务消费者等都要注册到Consul中,这样就可以实现服务提供者.服务消费者的隔离. 除了Consul之外,还有Eureka.Zookeeper等类似软件 ...
- Java基础知识➣多线程编程(五)
概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源, ...
- noi.ac 第五场第六场
t1应该比较水所以我都没看 感觉从思路上来说都不难(比牛客网这可简单多了吧) 第五场 t2: 比较套路的dp f[i]表示考虑前i个数,第i个满足f[i]=i的最大个数 i能从j转移需要满足 j< ...
- 【前端基础系列】slice方法将类数组转换数组实现原理
问题描述 在日常编码中会遇到将类数组对象转换为数组的问题,其中常用到的一种方式使用Array.prototype.slice()方法. 类数组对象 所谓的类数组对象,JavaScript对它们定义为: ...
- 【Android】Bitmap加载图片错误 java.lang.OutOfMemoryError: bitmap size exceeds VM budget
今天测试程序的时候出现下面的错误日志信息,程序当场挂掉 07-09 14:11:25.434: W/System.err(4890): java.lang.OutOfMemoryError: bitm ...
- Python_os模块
os模块:可以处理文件和目录,是Python系统和操作系统进行交互的一个接口 os模块常用方法: os.getcwd(): 获取当前工作目录,(即当前Python脚本工作的目录路径) os.chdir ...
- Kafka/Zookeeper集群的实现(二)
[root@kafkazk1 ~]# wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12. ...
- squid,nginx,lighttpd反向代理的区别
反向代理从传输上分可以分为2种: 1:同步模式(apache-mod_proxy和squid) 2:异步模式(lighttpd 和 nginx) 在nginx的文档说明中,提到了异步传输模式并提到它可 ...
- HDU-1013的解题报告
题目来源:hdu-1013 题意:正整数的数字根是通过求整数的整数而求出的.如果结果值是一个位数,那么这个数字就是数字根.如果结果值包含两个或多个数字,则将这些数字相加并重复该过程.只要需要获得一个数 ...
- Lua + win 10 + vs2017的运行环境和创建cocos2dx 3.17的lua项目(亲测)
转:https://blog.csdn.net/maoye198602102339/article/details/82047920 不管用什么引擎写游戏,脚本语言是少不了要接触的! 首先,我说的 ...