数据库事务中的基本概念
数
据库事务是指,由一个或多个SQL语句组成的工作单元,这个工作单元中的SQL语句相互依赖,如果有一个SQL语句失败,那么整个操作都要撤销。在并发环
境中,当多个事务同时访问同一资源时,可能会造成并发问题,此时可以使用数据库系统的事务隔离级别来避免各类并发问题。此外,在应用程序中还可以使用悲观
锁和乐观锁来解决丢失更新的并发问题。
数据库事务必须具备ACID的特征(Atomic原子性,Consistency一致性,Isolation隔离性,Durability持久性)
原子性,指整个数据库事务是不可分割的单元。只有所有的语句执行成功,才算成功。
一致性,指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
隔离性,指在并发环境中,当不同的事务同时操作相同的数据时,每个事务都有各自的完整数据空间。
持久性,指的是只要事务成功结束,对数据库做的更新要永久保存下来.
Transaction和Session的关系,应该注意以下几点
Transaction的rollback()和Session的close()方法都会抛出HibernateException
不论事务是否成功,最后都应该关闭Session。
即使事务中只包含只读操作,也应该在事务成功执行之后提交事务,并且在事务执行失败时撤销事务,因为在提交或撤销事务时,数据库系统会释放占用的资源。
多个事务同时运行时的并发问题
第一类丢失更新,撤销一个事务时,把其他事务已提交的更新数据覆盖了。
脏读,一个事务读到另一个事务未提交的更新数据。
虚读,一个事务读到另一个事务已提交的新插入的数据。
不可重复读,一个事务读到另一个事务已提交的更新数据。
第二类更新,一个事务覆盖另一事务已提交的更新数据。
数据库系统锁的基本原理
按照锁定的资源的粒度,锁可以分为以下类型
数据库级锁: 锁定整个数据库
表级锁: 锁定一张表
区域级锁: 锁定数据库的特定区域
页面级锁: 锁定数据库的特定页面
见面级锁: 锁定数据库的特定页面
键值级锁: 锁定数据库表中带有索引的一行数据。
行级锁: 锁定数据库表中的但行数据(即一条记录)
按照封锁的程度,锁可以分为: 共享锁,独占锁,更新锁
共享锁, 共享锁用于读数据操作,它是非独占的,允许其他事务同时读取其锁定的资源,但不允许其他事务更新数据。共享锁的特征:
加锁条件:当一个事务执行Select操作时,数据库系统就会为其分配一把共享锁,来锁定查询数据。
解锁条件:在默认情况下,数据读取完毕,共享锁就解除了。
与其他锁的兼容性:如果数据资源上放置了共享锁,还能再放置共享锁和更新锁。
并发性能:具有良好的并发性能,当多个事务读相同的数据时,每个事务都会获得共享锁,因此可以同时读锁定的数据。
独占锁,也叫排它锁,适用于修改数据的场合。它锁定的资源,其他事务不能读取也不能更新。独占锁具有以下特征:
加锁的条件:当一个事务执行insert、update、或delete语句时,数据库就会为SQL所操作的数据使用独占锁。如果数据上有其他锁,那么就能放置独占锁.
解锁条件:到事务结束时才能被解除
与其他锁的兼容性:独占锁不能和其他锁兼容。通用如果资源上有其他锁,那么也不能放置独占锁。
并发性能:性能较差,只允许有一个事务访问锁定的数据,如果其他事务也需要访问该数据,就必须等待,直到前一个事务结束,解除了独占锁,其他事务才有机会访问资源。
更新锁,在更新操作的初始化阶段用来锁定可能要被修改的资源,这可以避免使用共享锁造成死锁的现象。更新具有以下特征:
加锁的条件:当一个事务执行update语句时,数据库系统会先为事务分配一把更新锁。
解锁条件:读取数据完毕,执行更新操作时,会把更新锁升级为独占锁。
与其他锁的兼容性:更新锁与共享锁是兼容的。也就是说,一个资源可以同时放置更新锁和共享锁,但是最多只能放置一把更新锁。
并发性能:允许多个事务同时访问资源。但不允许修改。
死锁及其防止方法
合理安排表的访问顺序
使用短事务。将大事务分割为多个小事务执行。应该在处理事务之前就准备好用户必须提供的数据。
如果对数据的一致性要求不高,可以允许脏度。
如果可能,错开多个事务访问相同数据资源的时间,以防止锁冲突。
使用尽可能低的事务级别。
数据库的隔离级别
尽管数据库系统允许用户在事务中显示的为数据资源加锁,但是首先应该考虑让数据库系统自动管理锁,它会分析事务中的SQL语句,然后自动为SQL语句所操作的数据资源加上合适的锁,而且在锁的数目太多时,数据库系统会自动的进行锁升级,以提供系统性能。
数据库系统提供了四种事务隔离级别供用户选择:
Serializable,串行化。
一个事务在执行过程中完全看不到事务对数据库所做的更新。当两个事务同时操作数据库中的数据时,如果第一个事务已经在访问该数据,那么第二个事务只能停下来等待。
Repeatable Read:可重复读
一个事务在执行过程中可以看到其他事务已经提交的新插入的数据。但是不能看到其他事务对已有数据做的跟新。
Read Commited:读已提交数据
一个事务在执行过程中可以看到其他事务已经提交的新插入的数据。可以看到其他对已有数据进行的更新。
Read UnCommited:读取未提交
一个事务可以看到,其他事务没有提交新插入的数据。而且更新操作的记录也能看到。
//: 在hibernate.cfg.xml中配置
hibernate.connection.isolation=2
在应用程序中才用悲观锁和乐观锁
悲观锁与乐观锁的概念
悲观锁,在应用程序中显示的为数据资源加锁。可以防止丢失更新和不可重复读问题。但是会影响性能。
乐观锁,假设当前的事务操作的数据,不会有其他事务同时访问该数据资源,完全依靠数据库系统自动管理锁。因此可能会出现并发问题。
利用数据库系统的独占锁来实现悲观锁
悲观锁的两种实现方式
应用中显示的指定采用数据库系统的独占锁来锁定数据资源。
在数据库表中增加一个表明记录状态的LOCK字段,当它取值为Y时,表示该i记录已被某个事务锁定。如果为N,表示该条数据为空闲状态。
在Hibernate中,当通过Session的get()和load()方式来加载一个对象时,可以采用以下方式使用悲观锁:
Customer cus = (Customer)session.get(Customer.class, "c001", LockMode.UPGRADE); //: final org.hibernate.LockMode
LockMode类表示的几种锁定模式
锁定模式 描述
LockMode.NONE 如果在Hibernate缓存中存在Customer对象,就直接返回该引用。否则通过select加载。默认值
LockMode.READ 不管缓存中是否有,都使用select加载数据。如果映射文件设置了版本元素,就执行版本检查,比较缓存中的与取到的是否版本一致。
LockMode.UPGRADE 不管缓存中是否有,都使用select加载数据。就执行版本检查,比较缓存中的与取到的是否版本一致。如果数据库系统支持悲观锁,那么执行select…for update, 否则执行简单的select
LockMode.UPGRADE_NOWAIT 会执行LockMode.UPGRADE和它一样的功能。若果执行的select不能立即获得悲观锁,那么就会抛出异常
LockMode.WRITE 当Hibernate保存或更新对象时,会自动使用这种锁定模式。这种锁定模式只在Hibernate内部使用,所以在应用中不应该使用它
利用Hibernate的版本控制来实现乐观锁
create table Accounts (
id bigint primary key,
name varchar(15),
balance numeric(10,2),
LAST_UPDATED_TIME timestamp,
version int
)
在hbm中配置版本控制
//: 在元素必须跟在<id>元素的后面
<version name = "version" column = "VERSION" />
//: 使用该元素也可以实现版本控制
<timestamp name=”lastUpdateTime” column=” LAST_UPDATED_TIME” />
对游离对象进行版本检查
Session session1 = ....;
trans1 = session1.beginTransaction();
Account a = (Account)session1.get(Account.class, new Long(1));
trans1.commit();
session1.close();
a.setBalance(a.getBalance()-100);
Session session2 = ...;
trans2 = session2.beginTransaction();
session2.lock(a, LockMode.READ);
trans2.commit();
session2.close();
lock() 方法和update()方法之间的区别
lock()方法在LockMode.READ模式下,立即进行版本控制。而update()方法不会立即执行版本检查,只有当Session清理缓存时,真正执行update时才进行版本检查
lock()在默认的LockMode中不会执行update语句。而update()会计划执行一个update语句,如果数据库中没对应的记录那么会抛出异常。
实现乐观锁的其他方式
<class optimistic-lock="all" dynamic-update="true">
//: optimistic-lock=all/dirty 时必须设置dynamic-update为true
分享到:
相关推荐
数据库处理的经典资料: 叫你处理事务 如何并发处理 瞧瞧吧 机不可失哟
正确的调度是指多个事务并发执行时,其结果与某一串行调度的结果相同。可串行化的调度称为正确的调度。 七、并发调度的实例 设 T1、T2、T3 是三个事务:T1: A:=A+2, T2: A:=A*2, T3: A:=A*2。设 A 的初值为 0。...
8、数据库安全性管理、数据库事务及并发控制.sql
### 数据库事务总结 #### 一、事务的基本概念与特性 **事务**是数据库系统中的一个逻辑工作单元,它由一系列的操作组成,这些操作要么都完成,要么都不完成,以此来保证数据的一致性和完整性。 #### 二、事务的...
这是一个关于银行的数据库的处理,模仿的是从账户1转账给...那就需要用到事务,如果没有一起执行,就回滚。这个代码比较简单,希望对大家有帮助,自己建立一个数据库bank,在里面建立一个表Account,两属性:Id,money.
### 数据库事务并发与事务加锁 #### 一、数据库事务基本概念 在数据库领域,事务(Transaction)是由一系列操作组成的逻辑工作单元。事务具备四个关键特性:原子性(Atomicity)、一致性(Consistency)、隔离性...
- **可串行化调度**:虽然事务并发执行,但是其效果等同于串行调度。 #### 五、冲突可串行性 冲突可串行性是一种特殊的可串行化调度,其中只考虑了事务间的冲突操作。如果一个调度中所有的冲突操作都可以重新排列...
【Redis 事务与关系型数据库事务的比较】 Redis 和关系型数据库(如 MySQL)在事务处理上有显著的差异。在Redis中,事务提供了一种批量执行命令的方式,以确保原子性,但其机制与传统的ACID(原子性、一致性、隔离...
数据库实验报告:事务与并发控制.docx
随着越来越多的与大数据相关的应用程序系统的开发,NoSQL(不仅SQL)数据库系统变得越来越流行。 为了为某些NoSQL数据库系统添加事务功能,许多学者尝试了不同的技术。 不幸的是,在现有文献中缺乏对Redis交易的研究...
数据库思维导图——并发控制 并发控制 多事务执行方式 (1)事务串行执行 每个时刻只有一个事务运行,其他事务必须等到这个事务结束以后方能运行 不能充分利用系统资源,发挥数据库共享资源的...事务并发执行带来的问题
数据库并发控制是数据库管理系统中的关键组成部分,其目的是确保在多用户环境下,多个事务同时执行时,数据的完整性和一致性不受影响。并发控制的主要任务是防止事务间的不正确交互,如脏读、不可重复读和幻读等现象...
数据库事务处理是数据库管理系统中的核心概念,用于确保数据的一致性和完整性。事务是数据库操作的基本单元,它包含一组逻辑操作,这些操作要么全部执行,要么全部不执行,以确保数据的原子性。事务处理主要关注两个...
数据库事务处理和并发控制是数据库管理系统(DBMS)中的核心技术, Guarantees 数据库的可靠性和一致性。本文将详细介绍数据库事务处理和并发控制技术的概念、特性和实现机制。 一、事务处理概念 事务处理是数据库...
数据库并发控制是指在多用户环境下,当多个事务试图同时访问或修改同一数据时,数据库管理系统采取措施确保所有事务正确执行的过程。并发控制机制是衡量数据库管理系统性能的一个重要指标。如果没有适当的并发控制,...
此外,还有两阶段锁协议(2PL)、乐观并发控制(OCC)和并发事务调度算法如死锁检测与解除策略。 在恢复技术方面,数据库系统通常采用日志记录事务的操作,以便在系统崩溃或异常情况下,通过回滚未完成的事务和重做...
数据库并发事务处理是确保数据一致性和完整性的关键。通过理解事务的ACID特性、隔离级别和并发控制技术,开发者可以更有效地设计和优化数据库系统。提供的代码示例展示了如何在实际数据库操作中应用这些概念,帮助...