事务的定义

事务(Transaction)是构成单一逻辑工作单元的操作集合,要么完整地执行,要么完全不执行。不论发生何种情况,DBS必须保证事务能正确、完整地执行。

事务的ACID性质:

1.原子性(Atomicity)

一个事务对数据库的所有操作,是一个不可分割的工作单元。这些操作要么全部执行,要么什么也不做

保证原子性是数据库系统本身的职责,有DBMS的事务管理子系统来实现。

2.一致性(Consistency)

一个事务独立执行的结果,应保持数据库的一致性,即数据不会因事务的执行而遭受破会。

确保单个事务的一致性是编写事务的应用程序员的职责。在系统运行时,有DBMS的完整性子系统执行测试任务。

3.隔离性(Isolation)

在多个事务并发执行时,系统应保证与这些事务先后单独执行时的结果一样,此时称事务达到了隔离性的要求。也就是在多个事务并发执行时,保证执行结果是正确的,如同单用户环境一样。

隔离性是由DBMS的并发控制子系统实现的。

4.持久性(Durability)

一个事务一旦完成全部操作后,它对数据库的所有更新应永久地反映在数据库中,不会丢失。即使以后系统发生故障,也是如此。

持久性有DBMS的恢复管理子系统实现的。

并发操作带来的问题

在多用户共享系统中,许多事务可能同时对同一数据进行操作(“并发操作”),此时可能会破坏数据库的完整性。这里的”并发”(Concurrent)是指在单处理机(一个CPU)上,利用分时方法实行多个事务同时做。

DBMS的并发控制子系统,就是负责协调并发事务的执行,保证数据库的完整性,同时避免用户得到不正确的数据。

即使每个事务单独执行时时正确的,但多个事务并发执行时,如果系统不加以控制,任会破坏数据库的一致性,或者用户读了不正确的数据。数据库的并发操作通常会带来如下几个问题:丢失更新问题、读脏数据问题、不可重复读问题、幻读。

Ø  更新丢失(Lost Update)

当两个或多个事务选择同一行,然后基于最初选定的值更新该行,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题—最后的更新覆盖了由其他事务所做的更新。例如,两个编辑人员制作了同一文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的更改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一个文件,则可避免此问题。

Ø  脏读(Dirty Reads)

一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些”脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象地叫做”脏读”。

Ø  不可重复读(Non-Repeatable Reads)

一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变或某些记录已经被删除了!这种现象就叫做”不可重复读”。

Ø  幻读(Phantom Reads)

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为”幻读”。

1.       丢失更新问题

在表1-1中,数据库中A的初值是100,事务T1对A的值减30,事务T2对A的值增加1倍。如果执行次序是先T1后T2,那么结果A的值是140.如果是先T2后T1,那么A的值是170。这两种情况都应该是正确的。但是按表中的并发执行,结果A的值是200,这个值肯定是错误的,因为在时间t7丢失了事务T1对数据库的更新操作。因而这个并发操作是不正确的。

表1-1 在时间t7丢失了事务T1的更新

(FIND 表示从DB中读值,UPD表示把值写回到DB)

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

FIND A

t2

FIND A

t3

A:=A-30

t4

A:=A*2

t5

UPD A

t6

70

UPD A

t7

200

2.       读脏数据问题

这里有两种情况,用两个例子说明。

2.1 (用户读了”脏数据”,但没有破坏数据库的完整性)

在表1-2中,事务T1把A的值修改为70,但尚未提交(即未做COMMIT操作),事务T2紧跟着读未提交的A值(70)。随后,事务T1做ROLLBACK操作,把A的值恢复为100。而事务T2仍在使用被撤销了的A值70。在数据库技术中,把未提交的随后被撤销的数据称为”脏数据”。

表1-2 事务T2在时间t4读了未提交的A值

(FIND 表示从DB中读值,UPD表示把值写回到DB)

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

FIND A

t2

A:=A-30

t3

UPD A

t4

70

FIND A

t5

*ROLLBACK*

t6

100

2.2(用户读了”脏数据”,引起自身的更新操作被丢失,破坏了数据库的完整性)

在表1-2中,只是用户读了不正确的数据,而没有破坏数据库的完整性。但是表1-3的情况更糟,事务T2不仅在时间t4读了未提交的A值(70),而且实际上在时间t8还丢失了自己的更新操作。此时破坏了数据库的完整性。

表1-3 事务T2在时间t4读了未提交的A值,并在时间t8丢失了自己的更新

(FIND 表示从DB中读值,UPD表示把值写回到DB)

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

FIND A

t2

A:=A-30

t3

UPD A

t4

70

FIND A

t5

A:=A*2

t6

UPD A

t7

140

t8

*ROLLBACK*

t9

100

3.       不可重复读问题

表1-4表示T1需要两次读取同一数据项A,但是在两次读操作的间隔中,另一个事务T2改变了A的值。因此,T1在两次读同一数据项A时却读出了不同的值。

表1-4事务T1两次读取A的值,却得到了不同的结果

(FIND 表示从DB中读值,UPD表示把值写回到DB)

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

FIND A

t2

XFIND A

t3

A:=A*2

t4

UPD A

t5

200

COMMIT

t6

FIND A

这些问题都需要并发控制子系统来解决。譬如对于表1-1的丢失更新问题通常采用封锁(locking)技术加以解决:

1)         在时间t2应避免事务T2执行FIND操作。因为此时事务T1已读了A值,将要执行更新。或者

2)         在时间t5应避免事务T1执行UPD操作。因为事务T2已在使用A值。

锁(Lock)是一个与数据项相关的变量,对可能应用于该数据项上的操作而言,锁描述了该数据项的状态。

通常在数据库中每个数据项都有一个锁。锁的作用是使并发事务对数据库中数据项的访问能够同步。封锁技术中主要有两种封锁:排他型封锁(Exclusive Lock)【写锁】和共享型封锁(Shard Lock)【读锁】

Ø  排他型封锁(X锁)

如果事务T对某个数据R(可以是数据项、记录、数据集乃至整个数据库)实现了X锁,那么在T对数据R解除封锁之前,不允许其他事务T再对该数据加任何类型的锁。这种锁称为”X 锁”

使用X锁技术,可以解决表1-1的丢失更新问题。如何表1-5所示。事务T1先对A实现X锁,更新A值后,在COMMIT之后,事务T2再重新执行”XFIND A”操作,并对A进行更新(此时A已是事务T1更新过的值)。这样就能得出正确的结果。

表1-5等事务T1更新完成后再执行事务T2

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

XFIND A

t2

XFIND A(失败)

wait(等待)

t3

A:=A-30

wait

t4

wait

t5

UPD A

wait

t6

70

wait

t7

COMMIT(包括解锁)

wait

t8

XFIND A(重做)

t9

A:=A*2

t10

UPD A

t11

140

COMMIT(包括解锁)

Ø  共享型封锁(S锁)

采用X锁的并发控制度低,只允许一个事务独锁数据。而其他申请封锁的事务只能去排队去等。为此,降低要求,允许并发的读,就引入了共享型封锁(Shared Lock),这种锁简称为S 锁,又称为读锁。

定义:如果事务T对某数据加上S锁后,仍允许其他事务再对该数据加S锁,但在对该数据的所有S锁都解除之前决不允许任何事务对该数据加X锁。

使用S锁的操作有三个:

l  申请S锁操作”SFIND R”:表示事务对数据R申请加S锁,若成功,则可以读数据R,但不可以写数据R;若不成功,那么这个事务将进入等待队列,一直到获准S锁,事务才能继续做下去。

l  升级和写操作”UPDX R”:表示事务要把对数据R的S锁升级为X锁,若成功则更新数据R,否则这个事务进入等待队列。

l  解除S锁操作”SRELEASE R”:表示事务要解除对数据R的S锁。

可以看出,获准S锁的事务只能读数据,不能更新数据,若要更新,则先要把S锁升级为X锁。另外,由于S锁只允许读数据,因此解除S锁的操作不必非要合并到事务的结束操作中去,可以随时根据需要解除S锁。

使用S锁技术,也可以解决表1-1的丢失更新问题,但有可能出现表1-6所示的那种情况。也就是S锁解决了丢失更新问题,但同时又可能会引起另外一个问题-死锁。

表1-6更新未丢失,但在时间t6发生了死锁

时间

更新事务T1

数据库中A的值

更新事务T2

t0

100

t1

SFIND A

t2

SFIND A

t3

A:=A-30

t4

A:=A*2

t5

UPDX A(失败)

wait

t6

wait

UPDX A(失败)

t7

wait

wait

t8

wait

wait

事务的存取模式

SQL2允许事务有两种模式:

1.         READ ONLY(只读型):事务对数据库的操作只能是读操作。定义这个模式后,表示随后 的事务均是只读型。

2.         READ WRITE(读写型):事务对数据库的操作可以是读操作,也可以是写操作。定义这个模式后,表示随后的事务均是读写型。在程序开始时默认这种模式。

事务的隔离级别

SQL2提供事务的四种隔离级别让用户选择。这四个级别从高到低如下所述:

1.SERIALIZABLE(可串行化):允许事务与其他事务并发执行,但系统必须保证并发调度室可串行化,不致发生错误。在程序开始时默认这个级别。

2.REPEATABLE READ(可重复读):只允许事务读已提交的数据,并且在两次读同一数据时不允许其他事务修改此数据。

3.READ COMMITTED(读提交数据):允许事务读已提交的数据,但不要求”可重复读”。例如,事务对同一记录的两次读取之间,记录可能已经被提交的事务更新。

4.READ UNCOMMITTED(可以读未提交数据):允许事务读已提交或未提交的数据。这时SQL2中所允许的最低一致性级别。

上述四种级别可以用下列SQL语句定义:

SET TRANSACTIONN ISOLATION LEVEL SERIALIZABLE

SET TRANSACTIONN ISOLATION LEVEL REPEATABLE READ

SET TRANSACTIONN ISOLATION LEVEL READ COMMITTED

SET TRANSACTIONN ISOLATION LEVEL READ UNCOMMITTED

4种隔离级别比较

读数据一致性及允许的并发副作用

隔离级别

读数据一致性

脏读

不可重复读

幻读

未提交读

最低级别,只能保证不读取物理上损坏的数据

已提交读

语句级

可重复读

事务级

可序列化

最高级别,事务级

mysql 数据库并发限制_数据库的并发控制 - zhangjianyf的个人页面 - OSCHINA - 中文开源技术交流社区...相关推荐

  1. mysql连库串_数据库连接串整理 - osc_ac5z111b的个人空间 - OSCHINA - 中文开源技术交流社区...

    常用JDBC驱动与连接字符串 MySQL driver:com.mysql.jdbc.Driver url:jdbc:mysql://localhost:3306/mydb MySQL url格式:j ...

  2. mysql外码内码定义_中文编码杂谈(转) - CodeAxe的个人页面 - OSCHINA - 中文开源技术交流社区...

    编码问题的例子 在windows自带的notepad(记事本)程序中输入"联通"两个字,保存后再次打开,会发现"联通"不见了,代之以"��ͨ" ...

  3. leip与mysql数据库_性能分析方法 - osc_xm8bu282的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.性能分析的常用手段 1.空间换时间,利用内存缓存从磁盘上取出的数据,CPU可以直接访问内存,从而比从磁盘读取数据更高的效率. 2.时间换空间,当空间成为瓶颈的时候,切开数据分批次处理,用更少空间完 ...

  4. 清风 mysql_MySQL数据库 - 清风_的个人页面 - OSCHINA - 中文开源技术交流社区

    1.数据库my.cnf 配置 [root@localhost /]# cat /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/m ...

  5. java大作业用jsp数据库java_JSP数据库大作业 - 不是太阳也要发光的个人页面 - OSCHINA - 中文开源技术交流社区...

    本人QQ:240814476  欢迎大家提问,共同学习,共同进步. 最近做了一个数据库大作业啊,想用JSP做,发现代码量好大,在做前台的时候感觉手忙脚乱,没时间. 可能是本人拖了太久的原因吧 . 做的 ...

  6. php循环遍历数组保存数据库,php数组循环遍历 - 与狼共舞红队的个人空间 - OSCHINA - 中文开源技术交流社区...

    下面这三种是常用的 $_arr=array(); foreach($_arr as $key=>$value){ var_dump($key,$value); echo " " ...

  7. mysql查询去重第一条_Mysql用法记录 - Ashley-OSCHINA的个人空间 - OSCHINA - 中文开源技术交流社区...

    1.查询某个字段,在数据库不重复的条数(去重查询) select count(distinct item_uid) from supply_order; 查询 表 supply_order 中 ite ...

  8. mysql mcd date_mysql升级5.5 - ifeixiang的个人页面 - OSCHINA - 中文开源技术交流社区

    对付Linux的问题,其实很多都是权限问题,细心想一下即可. centos6.4默认装的是mysql5.1,使用 yum update 也update不了.google了一下,找到个yum安装的方法: ...

  9. mysql 安全扫描_MySQL 安全和监控 - Can't Wait Any Longer - OSCHINA - 中文开源技术交流社区...

    关于MySQL安全相关的监控和优化,以及数据运营. 5.5以后的版本添加了审计功能(类似于general_log,但是记录更详细),时时的审计会消耗一定的性能,因此离线分析也必不可少. 登录日志 创建 ...

  10. mysql+同步大师,mysql同步异常 - 低调的糊涂虫的个人页面 - OSCHINA - 中文开源技术交流社区...

    收到报警,数据库同步延迟 登上mysql服务器,查看进程,发现同步的state一直是"Reading event from the relay log" 而正常情况下,同步是很快的 ...

最新文章

  1. 人工智能十大流行算法
  2. Android 快捷方式的创建与查询 快捷方式问题大全 获取快捷方式在Launcher数据库中的信息 Failed to find provider info for com.android.la
  3. 负数比较大小_【教研活动】整体把握负数脉络 深度解读教材意图——鲤城区实验小学数学组单元整体教学系列研讨活动...
  4. Python的多进程锁的使用
  5. 使用Emacs执行外部shell命令
  6. HDU 3416 Marriage Match IV
  7. 【全网首发】言简意赅的Python全套语法,内附详细知识点和思维导图!【强烈建议收藏!】
  8. HTML5 浏览器检测
  9. 大数据和云计算技术周报(第101期)
  10. 趣味密码学入门--cryptohack
  11. OpenCV-Python在线参考手册
  12. HI618E音频解码芯片
  13. C++ 背包问题——多重背包
  14. RatingBar的使用
  15. 一个月薪12000的北京程序员的真实生活
  16. SAP客户端多语言设置
  17. NBIOT模块正常工作模式的三种工作状态(基于BC26)
  18. javascript实现自定义右键菜单(绑定鼠标左右键)
  19. pomelo客户端开发
  20. 关于屏幕取词的问题(转)

热门文章

  1. 在Windows中使用FileZilla Server创建FTP
  2. editplus破解源码
  3. PowerBuild安装不了怎么办?
  4. 网络流行简笔画图片大全,互联网图标简笔画
  5. linux64位wps下载授权码,ubuntu15.04安装wps-office的64位版
  6. js页面跳转并传递参数
  7. FPGA实现IIC协议(一)IIC总线协议
  8. 在rhel 7.3中安装glibc-devel-2.17-157.el7.i686包的过程详录
  9. 2.1 数值分析: 顺序Gauss消去法
  10. Github 星标 8K+ 这款国人开源的 Redis 可视化管理工具,真香...