事务 TRANSACTION
事务是数据库中一个但单独的执行单元(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的更多相关文章
- 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 ...
随机推荐
- Centos6.5 防火墙设置详解
vim /etc/sysconfig/iptables #丢弃所有进入请求 INPUT DROP [0:0] #丢弃所有转发请求 FORWARD DROP [0:0] #允许所有的output请求 O ...
- mysql里max_allowed_packet的作用
MySQL根据配置文件会限制Server接受的数据包大小.有时候大的插入和更新会受 max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置: 代码如下: show VAR ...
- Ext.require 的作用(转)
Ext.require:用到哪些组件,然后就预先加载,多余不用加载的组件 在实际环境中我们都会用 ext-all.js, 但是在开发调试的时候,我们使用 require 的话它可以动态加载单个的 js ...
- pytest 学习笔记一:参数化与组织分层
组织分层: 1.普通方式,和unittest分层类似: setup_module() # 通常放在类外 setup_class(cls) setup(self) teardown(self) tea ...
- c++中的类(class)-----笔记(类简介)
1, class 和 struct 都可以定义一个类,区别是两者在所支持的 默认信息隐藏方式不同:c++ 中默认为 private 类型,而 struct 中默认为 public 类型. 2,类的私有 ...
- 全国高校绿色计算大赛 预赛第一阶段(C++)第4关:计算日期
挑战任务 我们吃的食物都有保质期,现在食品监督管理局想要制作一个能准确计算食品过期日期的小程序,需要请你来进行设计. 例如:A食品在2018年1月1日生产,保质期是20天,则它的过期日期在2018年1 ...
- kraken-ejs创建一个项目【学习札记】
Keep in Touch. 保持联络. Who’s calling? 是哪一位? You did right. 你做得对. You set me up! 你出卖我! kraken-express-e ...
- Ubuntu虚拟机全屏问题
方法一:修改分辨率 xrandr查看能用的 xrandr -s 1920x1200改变. 方法二:安装新vmtools apt-get install open-vm-tools apt-get in ...
- day 26 初识进程,验证客户端合法性
验证客户端合法性: # 1.需要认证 # 程序和用户打交道的时候才会用到用户认证 # 对所有的客户端进行统一的认证 # 我现在要做的事情 # 写一个server端 # 写一个client端 特殊的 符 ...
- input 与raw_input的区别
input只能输入数字 raw_input 既可以输入数字也可以输入字符串 >>> input("input you name:") input you name ...