事务是数据库中一个但单独的执行单元(Unit),他通常由高级数据库操作语言(如SQL)或编程语言(如C++、Java)编写的用户程序的执行所引起。当在数据库中更改数据成功时,在事务中更改的数据便会提交,不再改变;否则,事务就取消或者回滚,更改无效。

事务必须满足四个属性:ACID

原子性(Atomicity):事物是一个不可分割的整体,为了保证事务的总体目标,事务必须具有原子性,即当数据修改时,要么全部执行,要么全部都不执行,即不允许事务部分的完成,避免只执行这些操作的一部分而带来的错误。

一致性(Consistency):如果事务出现错误,则回到最原始的状态。一个事务在执行之前和执行之后,数据库数据必须保持一致状态。由于并发操作带来的数据不一致性通常包括以下几种类型:丢失数据修改、“脏读”、不可重复读、“幻读”。

隔离性(Isolation):多个事务之间无法访问,只有当事务完成后才可以得到结果。即当两个或多个事务并发执行时,为了保证数据的安全性,将一个事务内部的操作隔离起来,不被其它正在进行的事务看到。数据库有四种类型的事务隔离级别:未提交的读、提交的读、可重复的读、串行化。

持久性(Durability):事务完成以后,DBMS保证它对数据库中数据的修改时永久性的。当一个系统崩溃时,一个事务依然可以提交,当事务完成后,操作结果保存在磁盘中,不会被回滚。持久性一般通过数据库备份与恢复来保证。

严格而言,数据库事务属性都是由数据库管理系统来进行保证的,在整个应用程序的运行过程中,应用程序无需去考虑数据库的ACID实现。

并发事务处理可能带来的问题

备注:数据库中读数据的一些概念

更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题——最后的更新覆盖其他事务所做的更新。

“脏读”(Dirty reads):一个事务读取了另一个事务尚未提交的数据。就是当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交到的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

不可重复读(Non-Repeatable Reads):一个事务的操作导致另一个事务在事务内两次读取到不同的数据,这是由于查询时系统中其他事务修改的提交引起的。比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。即在一个事务内,多次读同一个数据,在这个事务还没有结束时,另一个事务也访问该同一数据。那么在第一个事务的两次读数据之间,由于第二个事务的修改,使得第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此成为不可重复读,即原始读取不可重复。

“幻读”(Phantom Reads):一个事务的操作导致另一个事务前后两次查询的结果数据量不同。指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行;同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还没有修改的数据行,就如同发生的幻觉一样。

不可重复读和幻读的区别是:

不可重读读是指读到了已经提交的事务的更改数据(修改或者删除),即多次读一条记录,发现该记录中某些列值被修改过;防止不可重复读只需对操作的数据添加行级锁,防止操作中数据发生变化。

“幻读”是指读到了其他已经提交的事务的新增数据。即多次读一个范围内的记录,发现结果集不一致(记录增多或者减少);防止“幻读”,往往需要添加表级锁,将整张表锁定,防止新增记录。

事务的隔离级别

数据库的事务隔离越严格,并发副作用越小,但付出的代价也越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的。

为了解决“隔离”和“并发”的矛盾,定义了4个事务隔离级别

 事务隔离级别 读数据一致性 脏读 不可重复读 幻读
未提交读(Read uncommintted) 最低级别,只能保证不读取物理上损坏的数据
已提交读(Read committed) 语句级
可重复读(Repeatable read) 事务级
可序列化(Serializable) 最高级别,事务级

MySQL8.0默认的事务隔离级别是: 可重复读

MySQL8.0中查看当前的事务隔离级别

mysql> show variables like 'transaction_isolation';

JDBC中的五种事务隔离级别

为了解决与“多个线程请求相同数据”相关的问题,事务之间通常会用锁互相隔离开。大多数主流的数据库支持不同类型的锁。因此,JDBC

API 支持不同类型的事务,他们由Connection对象指派或确定(Connection的5个静态常量)。

① TRANSACTION_NONE  // 不支持事务

② TRANSACTION_READ_UNCOMMITTED  // 未提交读。说明在提交前一个事务可以看到另一个事务的变化。此事务级别下,允许“脏读”、不可重复读、“幻读”

③ TRANSACTION_READ_COMMITTED  // 已提交读。说明读取未提交的数据是不允许的。此事务级别下,不允许“脏读”,但允许不可重复读、“幻读”

④ TRANSACTION_REPEATEABLE_READ  // 可重复读。说明事务保证能够再次读取相同的数据而不会失败。此事务级别下,不允许“脏读”、不可重复读,但允许“幻读”

⑤ TRANSACTION_SERIALIZABLE  // 可序列化,这是最高的事务级别。不允许“脏读”、不可重复读、“幻读”

使用事务

MySQL中,事务用来管理 INSERT、UPDATE、DELETE语句,不能回退 SELETE语句。

默认情况下,事务是自动提交的。因此如果想要使用事务,必须先取消Connection的自动提交方式。

SQL中通过 SET AUTOCOMMIT=0 来设置
JDBC中通过调用 Connection的setAutoCommit(boolean) 方法来设置

设置事务隔离级别

SQL中使用 SET TRANSACTION 语句改变单个回话或者所有进程链接的隔离级别
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
JDBC中通过Connection的setTransactionisolation(int level) 来设置。参数即Connection的5个静态常量。

使用 START TRANSACTION 或者 BEGIN 语句开始一项新的事务。

使用 COMMIT 和 ROLLBACK 来提交或者回滚事务

使用 CHAIN 和 RELEASE 子句分别用来定义在事务提交或者回滚之后的操作。CHAIN会立即启动一个新的事务,并且和刚才的事务具有相同的隔离级别;RELEASE 则会断开和客户端的链接。

一般情况下,通过执行COMMIT(提交)或ROLLBACK(回滚)语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所做的一切更改就成为永久的,即被写入磁盘,而当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切更改都会被撤销,并且数据库中内容返回到事务开始之前所处的状态。无论什么情况,在事务完成是,都能保证回到一致状态。

事务 TRANSACTION的更多相关文章

  1. SQL Server 数据库的维护(三)__事务(transaction)和锁

    --维护数据库-- --事务(transaction)和锁-- --事务(transaction)-- --概述: 事务是指封装了一组T-SQL语句的单个逻辑单元.单元中的所有语句作为一个整体,在满足 ...

  2. JDBC中的事务-Transaction

    事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...

  3. Spring事务Transaction配置的五种注入方式详解

    Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...

  4. SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

    假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...

  5. FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)

    用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...

  6. 事务(Transaction)概念和特性

    http://baike.baidu.com/view/121511.htm 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库 ...

  7. redis源码分析之事务Transaction(下)

    接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...

  8. 数据库事务(Transaction)

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...

  9. 事务Transaction

    目录 为什么写这系列的文章 事务概念 ACID 并发事务导致的问题 脏读(Dirty Read) 非重复读(Nonrepeatable Read) 幻读(Phantom Reads) 丢失修改(Los ...

  10. jdbc、事务(Transaction)、批处理 回顾

    论文写的头疼,回顾一下jdbc,换换脑子 传统的写法: 1.加载驱动类 class.forname("jdbc类的包结构"); 2.获得连接 Connection conn=Dri ...

随机推荐

  1. StringBuild类

    每次拼接都会产生新的字符串对象,从而产生很多废弃的垃圾,拼的越多,垃圾越多,而利用StringBuilder来拼接字符串自始至终用的都是同一个StringBuilder容器 StringBuilder ...

  2. c#中连接数据库

    配置文件web.config: <connectionStrings> <add name="eport" connectionString="Data ...

  3. JIT物料在途未清PO作为供给

    以下是本应在TEMP中处理,目前是写到FP_CHECK_SAP_DATA中 ----JIT物料在途未清PO作为供给 add by landor on 20180809 INSERT INTO SAP_ ...

  4. .sh_history文件的管理机制

    来源:http://www.aixchina.net/Article/27258 字数 1056阅读 4365评论 1赞 0 内容提要: .sh_history是在ksh中用于存储用户在shell中输 ...

  5. 将MYSQL的GBK数据库转成_UTF-8数据库的简便方法

    http://wenku.baidu.com/link?url=epKvsEtUbtzdjQEezGdFMDvJiro3X1yKNgb-1cXzi7CEoYhtoJhImkuyTvVgSmfL6AQL ...

  6. python 进行机器学习

    summary: 本文总结了几种常见的线性回归的的方式以及各种方式的优缺点. 1,简单现性回归(OSL): OSL:就是一种最为简单的普通最小二乘法的实现,y = a0 + a1*x1 + a2*x2 ...

  7. pta l2-8(最长对称字串)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805067704549376 题意:求给定字符串的最长回文串的长 ...

  8. [剑指offer]51-数组中的逆序对(归并排序)

    题目链接 https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5 题意 在数组中的两个数字,如果前面一个数 ...

  9. 项目总结09:select标签下封装option标签

    项目中经常用到Select标签,用封装好的方法获取option,可以避免冗赘的代码: 1.JSP--标签 <select class="width_md" name=&quo ...

  10. java_2变量和运算符

    1.变量 存储数据的容器. 2.变量创建的3要素 数据类型 变量名 = 变量值: 如int  a = 10; 3.数据类型的自动转化 当小范围变量向大范围变量转化的时候,会发生这种情况.如int类型变 ...