【持久层】数据库事务基础——事务的隔离级别

内容导读:

前三节数据库事务、并发带来的风险以及数据库锁都是为了铺垫事务的隔离性。

事务的隔离性不是无缘无故就存在的,他的存在是为了解决某一类问题,带来某一些操作的便捷;解决的问题是指数据库并发操作中数据一致性保证,带来的便捷是指定义好隔离级别之后,数据库会为操作自动加锁(不同的隔离级别拥有不同的自动锁粒度),而不用每次操作都手动的加锁。

写着写着觉得没什么可写的,本文已沦为简单的笔记····

一、数据库事务

将一组数据库操作看作一个具备特殊数据库语义的执行单元,该执行单元具备ACID的事务属性。在数据库事务的ACID属性中,原子性、隔离性和持久性都是为了保证数据的一致性。ACID的数据库语义如下所示。

1. atomic(原子性)

该执行单元中的所有操作,要么全部执行成功,要么全部不执行。

2. consistency(一致性)

执行单元执行完成前后的状态是一致的。一个转账的例子加以说明。

转账前状态:A账户1000块,B账户1000块,转账前的状态是A+B=2000块;

执行单元操作:A向B转账200块;

转账后状态:A账户800块,B账户1200块,转账后的状态是A+B=2000块;

结论:转账前和转账后的状态一致,都是2000块;并没有发生状态不一致情况导致账户A、账户B或银行中任何一方受损或受益。

3. isolation(隔离性)

隔离性描述的是数据库对待并发操作的态度,即在并发操作数据库的环境下,不同事务之间对彼此造成影响的程度。根据用户对数据一致性环境的需求,数据库支持不同的隔离级别。

千万要注意,在数据库并发环境下讨论隔离性才有意义,本质上数据库的隔离级别就是自动事务的代名词。更多细节,下文详细讨论。

4. durability(持久性)

持久性描述的是当事务成功提交之后,提交数据会被持久化到数据库中,即使数据库立即崩溃,也能够在重启的时候恢复。持久性基于操作日志,简单来说,就是记录数据库操作语句,一条数据库语句包含了数据库的操作和数据,因此只要日志不受损,即使数据库存储介质损坏,也能够通过日志恢复。

二、并发带来的风险

并发操作数据库会导致一些风险,这些风险可以归类为三类读问题和两类更新问题。

1. 脏读

一个事务中读到另一个事务未提交的update。如下图所示,事务A中读到了事务B中未提交的操作,从而导致出现数据不一致的状况。

2. 不可重复度

一个事务中读到另一个事务提交的update。和脏读的区别是,读到的update事务是否已被提交。

读到另一个事务提交的update在大多数情况下无伤大雅,但是如果是在月底做报表的时候,这种情况就出问题了。你需要统计上一个月的数据,但是在统计过程中不断有update,即便你在准确的时间点开启了事务,但是统计的数据依然不准确。解决的办法是为数据库加锁,但是如果你觉得每次统计都重复相同的动作会很麻烦,可以设置隔离级别,让数据库为你自动加锁。

3. 虚读

一个事务中读到另一个事务提交的insert。和不可重复读的区别是,一个是读到提交的update,一个是读到提交的insert。

借用不可重复读中月底报表的例子,读到提交的update,这意味着数据库中原来就存在该条记录,这是修改了字段;而读到insert,则意味着数据库中原来是不存在这条记录的。虽然在统计的sql中添加了where的时间条件,但是读到存在此前的记录和不存在的记录,显然事务之间的影响程度是不一样的。

4. 第一类丢失更新

一个事务的回滚覆盖了另一个事务提交的update。这类丢失更新对数据库造成的影响是很严重的,除非数据库不支持事务,否则无论哪一种隔离级别都必须防止该风险。

5. 第二类丢失更新

一个事务提交的update覆盖了另一个事务提交的update。

三、数据库锁

锁不外乎独占锁和共享锁,放在数据库环境中有行锁和表锁,再细粒度分下来,行共享锁、行独占锁、表共享锁、表独占锁、表共享行独占锁。数据库锁和程序中的锁作用相似,都是为了解决并发环境中的风险——安全性、活跃性和性能问题。

实际上,数据库在并发环境中出现的问题都可以通过加锁来得到解决,本质上也是这么来干的,但是很多加锁操作都是相似的,没必要一直重复相同的动作,因此出现了事务的隔离级别。

MySQL锁详解:点击打开链接

四、事务隔离级别

1. isolation的意义

要解决数据库并发中出现的问题,和写java代码一样,需要通过锁来获取正确的执行时序,这样一来,每次执行操作前都要先执行sql中关于锁的语句,为了简便操作,于是通过设置数据库隔离级别,让数据库自动加锁。

2. isolation的详解

ANSI/ISO SQL 92标准定义了4个等级的隔离级别,分别是READ_UNCOMMITED、READ_COMMITED、REPETABLE_READ、SERIALIZABLE,四个等级的隔离成都递增,允许的并发程度递减,其中mysql默认支持第三种隔离级别,oracle默认支持第二种隔离级别。

关于隔离级别的一些简单操作。

mysql> SELECT @@tx_isolation;//查看当前事务的隔离级别
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set

mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;//临时更改数据库隔离级别,仅对本次会话有效
Query OK, 0 rows affected

mysql> SELECT @@tx_isolation;//查看已经被更改的隔离级别
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set

数据库隔离级别对并发问题的解决情况。

五、JDBC对事务的支持

JDBC编程中,所有和事务有关的操作都被封装到了connection对象中(by the way,connection的实现被封装成了虚引用保存在driver的ConcurrentHashMap中),源码节选及注释如下。

/**
* com.mysql.jdbc.ConnectionImpl:mysql对connection接口的实现类
*/
public interface java.sql.Connection  extends Wrapper, AutoCloseable {
	/**
     * A constant indicating that transactions are not supported.
	 * 没有事务情况的也不存在隔离级别
     */
    int TRANSACTION_NONE = 0;

    /**
     * A constant indicating that
     * dirty reads, non-repeatable reads and phantom reads can occur.
     * This level allows a row changed by one transaction to be read
     * by another transaction before any changes in that row have been
     * committed (a "dirty read").  If any of the changes are rolled back,
     * the second transaction will have retrieved an invalid row.
	 * 除了第一类丢失更新之外,三类读问题和第二类都是更新都会发生
     */
    int TRANSACTION_READ_UNCOMMITTED = 1;

    /**
     * A constant indicating that
     * dirty reads are prevented; non-repeatable reads and phantom
     * reads can occur.  This level only prohibits a transaction
     * from reading a row with uncommitted changes in it.
	 * 防止脏读和第一类丢失更新
     */
    int TRANSACTION_READ_COMMITTED   = 2;

    /**
     * A constant indicating that
     * dirty reads and non-repeatable reads are prevented; phantom
     * reads can occur.  This level prohibits a transaction from
     * reading a row with uncommitted changes in it, and it also
     * prohibits the situation where one transaction reads a row,
     * a second transaction alters the row, and the first transaction
     * rereads the row, getting different values the second time
     * (a "non-repeatable read").
	 * 防止脏读、不可重复读和第一类丢失更新、第二类丢失更新,不能防止虚读
     */
    int TRANSACTION_REPEATABLE_READ  = 4;

    /**
     * A constant indicating that
     * dirty reads, non-repeatable reads and phantom reads are prevented.
     * This level includes the prohibitions in
     * <code>TRANSACTION_REPEATABLE_READ</code> and further prohibits the
     * situation where one transaction reads all rows that satisfy
     * a <code>WHERE</code> condition, a second transaction inserts a row that
     * satisfies that <code>WHERE</code> condition, and the first transaction
     * rereads for the same condition, retrieving the additional
     * "phantom" row in the second read.
	 * 防止脏读、不可重复读、虚读,第一类、第二类丢失更新,此时数据库相当于串行处理事务,并发程度最低
     */
    int TRANSACTION_SERIALIZABLE     = 8;

	/**
	* Are we in autoCommit mode?
	* JDBC默认是自动提交事务,每次操作数据库都自动进行事务
	*/
	private boolean autoCommit = true;
	/**
	* 连接对象支持的事务操作:
	* 关于setAutoCommit,因为JDBC默认是自动提交事务,也就是执行一个SQL语句就会提交一次事务,因此如果要想控制事务的提交,设置autoCommit为false即可;
	* 这里设置autoCommit为false,并没有和数据库交互,实际上数据库的隔离级别设置的自动事务并不受影响,这句代码只影响JDBC
	*/
	void setAutoCommit(boolean autoCommit) throws SQLException;
	void commit() throws SQLException;
	void rollback() throws SQLException;
	void setTransactionIsolation(int level) throws SQLException;
	int getTransactionIsolation() throws SQLException;
	Savepoint setSavepoint() throws SQLException;
	Savepoint setSavepoint(String name) throws SQLException;
	void rollback(Savepoint savepoint) throws SQLException;

}

附注:

写到最后已经不想写了,后面很多深入的东西略了,sorry

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-25 18:51:40

【持久层】数据库事务基础——事务的隔离级别的相关文章

mysql的事务四个特性以及事务的四个隔离级别

一.事务四大属性 分别是原子性.一致性.隔离性.持久性. 1.原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响. 2.一致性(Consistency) 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态.举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账.转几次账,事务

事务的特性与隔离级别

事务的定义: 简单的说事务就是一组原子性的SQL语句.我们可以将这组语句理解为一个工作单元,要 么全都执行,要不都不执行. 事物的四大特性(简称ACID): 原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部提交成功,要么全部失败回滚. 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致. 隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的.一个事务所做的修改在提交之前

【综合】事务的处理及隔离级别

原文地址:http://blog.csdn.net/qiaoge134/article/details/20031949 事务的隔离级别: 先说说 (通俗说) 1. 脏读:是一个事务读取了  其他事务没有提交的数据. 2.不可重复度:就是第一次读和第二次读,两次读到的 数据不一致,原因是:在此期间有其他的事务修改了数据. 3.幻读:就是第一次读和第二次读,两次读到的 数据不一致, 原因是:在此期间有事务插入了新的数据(区别于不可重复读:不可重复读是  对于修改操作而言,幻读对插入造作而言) 事务

MySQL数据库中的四种隔离级别

原文:MySQL数据库中的四种隔离级别 事务的隔离性比想象的要复杂,在 SQL 标准中定义了四种级别的隔离级别.通常而言,较低级别的隔离通常可以执行更高的并发,系统的开销也更低 READ UNCOMMITTED 该级别为未提交读.在该级别中,事务中的修改即使没有提交,对其他事务也都是可见的.事务可以读取未提交的数据,这也被称为脏读.这个级别会导致很多的问题,从性能上来说,它不会比其他级别好太多,但缺乏其他级别的很多好处.除非真的有非常必要的理由,在实际应用中一般很少使用. READ COMMIT

数据库事务的四种隔离级别

数据库事务的隔离级别有4个,由低到高依次为: Read uncommitted 未授权读取 读未提交 读可允许其他两个事务不能同时进行写操作 事务B读取事务A为提交的数据 避免更新丢失 会出现脏读 Read committed 授权读取 读提交 读可允许其他 未提交的事务禁止其他事务访问进行 事务A读取数据 事务B更改数据 事务A读取B更改后的数据,前后结果不一致 避免脏读 会出现不可重复读(重复读取结果不同) Repeatable read 可重复读取 读不允许写事务进行 写禁止其他事务进行

数据库事务、特性及隔离级别

一.事务    事务(Transaction)是并发控制的基本单位.所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.而这些逻辑工作单元需要具有原子性,  一致性,隔离性和持久性四个属性,统称为ACID特性. 二.事务的4个基本特征   ●  原子性(Atomic):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败. ●  一致性(Consistency):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态.

MySQL事务及实现、隔离级别及锁与优化

事务  事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.事务是逻辑上的一组操作,要么都执行,要么都不执行. ACID简介 原子性(Atomicity).一致性(Correspondence).隔离性(Isolation).持久性(Durability). (1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一

网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别

1.1.1 API详解:注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 原因有2个: >导致驱动被注册2次. >强烈依赖数据库的驱动jar 解决办法: Class.forName("com.mysql.jdbc.Driver"); 1.1.2 API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果 String sql = "某SQL语句&qu

Java Web(八) 事务,安全问题及隔离级别

事务 什么是事务? 事务就是一组原子性的SQL查询,或者说是一个独立的工作单元. 事务的作用 事务在我们平常的CRUD(增删改查)操作当中也许不太常用, 但是如果我们有一种需求,一组操作中必须全部成功执行,才算完成任务,只要有一个出错了,那么所有的任务都将回到最初的状况,恢复原样.那么这就需要使用事务了.如: 银行转账,购买飞机票... 事务的特性 事务具有4个特性(ACID):原子性(Atomicity).一致性(Consistency).隔离性(lsolation).持久性(Durabili