Java事务详解

fbb6d8ff376d4b04ab79be7667984a0e.gif一、事务的理解:

 

 

1、事务的特性:

 

  1) 原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。

 

  2) 一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。

 

  3) 隔离性(isolation):一个事务的执行不能被其他事务所影响。

 

  4) 持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即使此时再执行回滚操作也不能撤消所做的更改。

 

2、事务的定义:

 

  事务(Transaction):是并发控制的单元,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,sql server 能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。

 

  事务通常是以begin transaction开始,以commit或rollback结束:

 

  Commint表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据的更新写回到磁盘上的物理数据库中去,事务正常结束。

 

  Rollback表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态。

 

3、事务的分类:

 

  自动提交事务:每条单独的语句都是一个事务。每个语句后都隐含一个commit。 (默认)

 

  显式事务:以begin transaction显示开始,以commit或rollback结束。

 

  隐式事务:当连接以隐式事务模式进行操作时,sql server数据库引擎实例将在提交或回滚当前事务后自动启动新事务。无须描述事物的开始,只需提交或回滚每个事务。但每个事务仍以commit或rollback显式结束。连接将隐性事务模式设置为打开之后,当数据库引擎实例首次执行下列任何语句时,都会自动启动一个隐式事务:alter table,insert,create,open ,delete,revoke ,drop,select, fetch ,truncate table,grant,update在发出commit或rollback语句之前,该事务将一直保持有效。在第一个事务被提交或回滚之后,下次当连接执行以上任何语句时,数据库引擎实例都将自动启动一个新事务。该实例将不断地生成隐性事务链,直到隐性事务模式关闭为止。

 

二、Java JDBC事务机制:

 

  首先,我们来看看现有JDBC操作会给我们带来什么重大问题,比如有一个业务:当我们修改一个信息后再去查询这个信息,看是这是一个简单的业务,实现起来也非常容易,但当这个业务放在多线程高并发的平台下,问题自然就出现了,比如当我们执行了一个修改后,在执行查询之前有一个线程也执行了修改语句,这是我们再执行查询,看到的信息就有可能与我们修改的不同,为了解决这一问题,我们必须引入JDBC事务机制,其实代码实现上很简单,一下给出一个原理实现例子供大家参考:

 

复制代码

private Connection conn = null;  

private PreparedStatement ps = null;  

try {  

    conn.setAutoCommit(false); //将自动提交设置为false  

    ps.executeUpdate("修改SQL"); //执行修改操作  

    ps.executeQuery("查询SQL"); //执行查询操作                 

    conn.commit(); //当两个操作成功后手动提交  

} catch (Exception e) {  

    conn.rollback(); //一旦其中一个操作出错都将回滚,使两个操作都不成功  

    e.printStackTrace();  

}

复制代码

三、与事务相关的理论:

1、事务(Transaction)的四个属性(ACID)

  原子性(Atomic) 对数据的修改要么全部执行,要么全部不执行。

  一致性(Consistent) 在事务执行前后,数据状态保持一致性。

  隔离性(Isolated) 一个事务的处理不能影响另一个事务的处理。

  持续性(Durable) 事务处理结束,其效果在数据库中持久化。

 

2、事务并发处理可能引起的问题

 

  脏读(dirty read) 一个事务读取了另一个事务尚未提交的数据,

 

  不可重复读(non-repeatable read) 一个事务的操作导致另一个事务前后两次读取到不同的数据

 

  幻读(phantom read) 一个事务的操作导致另一个事务前后两次查询的结果数据量不同。

 

  举例:事务A、B并发执行时:

 

  当A事务update后,B事务select读取到A尚未提交的数据,此时A事务rollback,则B读到的数据是无效的"脏"数据。

 

  当B事务select读取数据后,A事务update操作更改B事务select到的数据,此时B事务再次读去该数据,发现前后两次的数据不一样。

 

  当B事务select读取数据后,A事务insert或delete了一条满足A事务的select条件的记录,此时B事务再次select,发现查询到前次不存在的记录("幻影"),或者前次的某个记录不见了。

 

四、JDBC的事务支持:

 

  JDBC对事务的支持体现在三个方面:

 

1、自动提交模式(Auto-commit mode):

 

  Connection提供了一个auto-commit的属性来指定事务何时结束。

 

  (1)当auto-commit为true时,当每个独立SQL操作的执行完毕,事务立即自动提交,也就是说每个SQL操作都是一个事务。

 

  一个独立SQL操作什么时候算执行完毕,JDBC规范是这样规定的:

 

  对数据操作语言(DML,如insert,update,delete)和数据定义语言(如create,drop),语句一执行完就视为执行完毕。

 

  对select语句,当与它关联的ResultSet对象关闭时,视为执行完毕。

 

  对存储过程或其他返回多个结果的语句,当与它关联的所有ResultSet对象全部关闭,所有update count(update,delete等语句操作影响的行数)和output parameter(存储过程的输出参数)都已经获取之后,视为执行完毕。

 

  (2)当auto-commit为false时,每个事务都必须显示调用commit方法进行提交,或者显示调用rollback方法进行回滚。auto-commit默认为true。

 

  JDBC提供了5种不同的事务隔离级别,在Connection中进行了定义。

 

2、事务隔离级别(Transaction Isolation Levels)

  JDBC定义了五种事务隔离级别:

  TRANSACTION_NONE JDBC驱动不支持事务

  TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。

  TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。

  TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。

  TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读。

 

3、保存点(SavePoint)

 

  JDBC定义了SavePoint接口,提供在一个更细粒度的事务控制机制。当设置了一个保存点后,可以rollback到该保存点处的状态,而不是rollback整个事务。

 

  Connection接口的setSavepoint和releaseSavepoint方法可以设置和释放保存点。

 

  JDBC规范虽然定义了事务的以上支持行为,但是各个JDBC驱动,数据库厂商对事务的支持程度可能各不相同。如果在程序中任意设置,可能得不到想要的效果。为此,JDBC提供了DatabaseMetaData接口,提供了一系列JDBC特性支持情况的获取方法。比如,通过DatabaseMetaData.supportsTransactionIsolationLevel方法可以判断对事务隔离级别的支持情况,通过DatabaseMetaData.supportsSavepoints方法可以判断对保存点的支持情况。

 

五、事务的使用:

 

  当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,并且保证这些语句是在同一时间共同执行的时,我们就应该为这多条语句定义一个事务。

 

    其中,银行转账这一事例,最能说明,使用事务的重要性了。

 

update from account set money=money-100 where name=‘a’;

update from account set money=money+100 wherename=‘b’;

//因为这时,两个账户的增减变化是在一起执行的。现实生活中这种类似于同步通信的例子还有很多,这里,不再赘述。

  当然,对于事务的编写,也是要遵守一定的顺序的:

 

  首先,设置事务的提交方式为非自动提交:conn.setAutoCommit(false);

 

  接下来,将需要添加事务的代码放入try catch块中。

 

  然后,在try块内添加事务的提交操作,表示操作无异常,提交事务。conn.commit();

 

  尤其不要忘记,在catch块内添加回滚事务,表示操作出现异常,撤销事务:conn.rollback();

 

  最后,设置事务提交方式为自动提交:conn.setAutoCommit(true);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/170885.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

同城小程序怎么运作 本地化生活小程序开发

同城小程序可以采取公域加私域的运营方式,进行运作。 在社交媒体平台上分享有趣的本地生活内容、社区动态,可以通过举办本地活动、合作推广等方式进行线下宣传,可以通过抖音本地化生活服务进行线下门店推广。 本地化生活小程序开发需要结合自…

22.构造一个关于员工信息的结构体数组,存储十个员工的信息

结构体问题。构造一个关于员工信息的结构体数组,存储十个员工的信息,包括员工工号,员工工资,员工所得税,员工实发工资。要求工号和工资由键盘输入,并计算出员工所得税(所得税工资*0.2&#xff0…

Go的优雅退出

Go优雅退出/停机以前主要通过signal来实现,当然现在也是通过signal来实现,只是从go 1.16开始,新增了更加友好的API: func NotifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) 该…

计算复杂性理论(一)图灵机

计算复杂性理论(一)图灵机 一台 k-带图灵机(TM)M 有 k-条带子。第一条带子称为输入带,用来存放输入数据,输入带是只读带。其余 k−1 条带子是工作带,既可以从工作带上读信息,也可以…

C# 并发编程

C# 并发编程 前言 对于现在很多编程语言来说,多线程已经得到了很好的支持, 以至于我们写多线程程序简单,但是一旦遇到并发产生的问题就会各种尝试。 因为不是明白为什么会产生并发问题,并发问题的根本原因是什么。 接下来就让…

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转,Kotlin

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <FrameLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app&q…

优雅关闭TCP的函数shutdown效果展示

《TCP关闭的两种方法概述》里边理论基础&#xff0c;下边是列出代码&#xff0c;并且进行实验。 服务端代码graceserver.c的内容如下&#xff1a; #include "lib/common.h"static int count;static void sig_int(int signo) {printf("\nreceived %d datagrams\…

Jenkins简介及Docker Compose部署

Jenkins是一个开源的自动化服务器&#xff0c;用于自动化构建、测试和部署软件项目。它提供了丰富的插件生态系统&#xff0c;支持各种编程语言和工具&#xff0c;使得软件开发流程更加高效和可靠。在本文中&#xff0c;我们将介绍Jenkins的基本概念&#xff0c;并展示如何使用…

Vue3 源码解读系列(三)——组件渲染

组件渲染 vnode 本质是用来描述 DOM 的 JavaScript 对象&#xff0c;它在 Vue 中可以描述不同类型的节点&#xff0c;比如&#xff1a;普通元素节点、组件节点等。 vnode 的优点&#xff1a; 抽象&#xff1a;引入 vnode&#xff0c;可以把渲染过程抽象化&#xff0c;从而使得组…

区块链拆分

随着区块链技术的发展和普及&#xff0c;去中心化钱包逐渐成为数字货币领域的重要工具。去中心化钱包不仅具有高度安全性和隐私保护能力&#xff0c;还可以通过智能合约和开源技术实现定制化功能。本文将探讨去中心化钱包定制开发的基本概念、优势、流程和前景。 一、去中心化钱…

SpringBoot实现Excel导入导出

SpringBoot实现Excel导入导出 在我们平时工作中经常会遇到要操作Excel的功能&#xff0c;比如导出个用户信息或者订单信息的Excel报表。你肯定听说过 POI这个东西&#xff0c;可以实现。但是POI实现的API确实很麻烦&#xff0c;它需要写那种逐行解析的代码&#xff08;类似Xm…

初始MySQL(五)(自我复制数据,合并查询,外连接,MySQL约束:主键,not null,unique,foreign key)

目录 表复制 自我复制数据(蠕虫复制) 合并查询 union all(不会去重) union(会自动去重) MySQL表的外连接 左连接 右连接 MySQL的约束 主键 not null unique(唯一) foreign key(外键) 表复制 自我复制数据(蠕虫复制) #为了对某个sql语句进行效率测试,我们需要海量…