事务的四个属性 :原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability) 。
1. 原子性(Atomic)
最重要的原则,也是最容易理解的原则。被事务管理的所有方法,要么一起被提交,要么一起回滚。
2. 一致性(Consistency)
事务在系统完整性中实施一致性,如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于新有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
3. 隔离性(Isolation)
在隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在 系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数 据。重要的是,在隔离状态执行事务,系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的事务中,系统的状态可能会发生 变化。如果事务不是在隔离状态运行,它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事务隔离,可以阻止这类事件的发生。
4. 持久性(Durability)
持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在日志中记录事务完成的任务进行重建。
数据库锁概念:
在数据库中有两种基本的锁类型:排它锁 (Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两 种基本的锁类型来对数据库的事务进行并发控制。
从程序员的角度看,锁分为以下两种类型:
1.乐观锁(Optimistic Lock)
乐观锁假定在处理数据时,不需要在应用程序的代码中做任何事情就可以直接在记录上加锁、即完全依靠数据库来管理锁的工作。一般情况下,当执行事务处理时SQL Server会自动对事务处理范围内更新到的表做锁定。
2.悲观锁(Pessimistic Lock)
悲观锁对数据库系统的自动管理不感冒,需要程序员直接管理数据或对象上的加锁处理,并负责获取、共享和放弃正在使用的数据上的任何锁。
事务隔离级别
一个事务必须与其它事务进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较高的隔离级别可以确保数据的正确性,但可能对并发产生负面影响。
数据库并发操作存在的异常情况:
1. 更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔离开来
2. 脏读取(Dirty Reads):一个事务开始读取了某行数据但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险很可能所有操作都被回滚
3. 不可重复读取(Non-repeatable Reads):一个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交
4. 两次更新问题(Second lost updates problem):无法重复读取特例,有两个并发事务同时读取同一行数据然后其中一个对它进行修改提交而另一个也进行了修改提交这就会造成第一次写操作失效
5. 幻读(Phantom Reads):也称为幻像(幻影)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的
事务隔离级别
为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。
1. 未 授权读取(Read Uncommitted):也称未提交读。允许脏读取但不允许更新丢失,如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务 读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。
2. 授 权读取(Read Committed):也称提交读。允许不可重复读取但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访 问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。
3. 可 重复读取(Repeatable Read):禁止不可重复读取和脏读取。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事 务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。
4. 串 行(Serializable):也称可串行读。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过 “行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务 在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。
隔离级别 | 更新丢失 | 脏读取 | 重复读取 | 幻读 |
未授权读取 | N | Y | Y | Y |
授权读取 | N | N | Y | Y |
可重复读取 | N | N | N | Y |
串行 | N | N | N | N |
============================================================================
ORACLE的默认事务级别:READ COMMITTED
ORACLE支持的事务隔离级别:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION ISOLATION LEVEL READ ONLY;
咨询了DBA,java中设了这样oracle不支持的隔离级别,应该是没有用的。这点我还没有证实。忘有人证实过告知~3KS
少数数据库默认的隔离级别为Repeatable Read, 如MySQL InnoDB存储引擎
即使是最低的级别,也不会出现 第一类 丢失 更新问题 .
======================= 上面红色部分的问题我已经写代码证实了 ===============
见以下异常栈:
- Exception in thread "main" org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: 仅 READ_COMMITTED 和 SERIALIZABLE 是有效的事务处理级
- at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:238)
- at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:374)
- at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:125)
- at com.yajun.ibatis.TransactionTest.main(TransactionTest.java:19)
- Caused by: java.sql.SQLException: 仅 READ_COMMITTED 和 SERIALIZABLE 是有效的事务处理级
- at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
- at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131)
- at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:197)
- at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:261)
- at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:269)
- at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:490)
- at oracle.jdbc.driver.PhysicalConnection.setTransactionIsolation(PhysicalConnection.java:4070)
- at org.apache.commons.dbcp.DelegatingConnection.setTransactionIsolation(DelegatingConnection.java:380)
- at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setTransactionIsolation(PoolingDataSource.java:343)
- at org.springframework.jdbc.datasource.DataSourceUtils.prepareConnectionForTransaction(DataSourceUtils.java:174)
- at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:210)
- ... 3 more
spring设置了oracle不支持的数据库事务级别会报异常。。
相关推荐
2. **设置事务隔离级别**:使用Connection对象的setTransactionIsolation()方法。 3. **开始事务**:调用Connection对象的setAutoCommit(false),这会关闭自动提交模式,从而开始手动事务控制。 4. **执行SQL操作**...
串行化级别是一种事务隔离级别,它保证事务的执行顺序,避免了幻读等并发问题。不同的隔离级别对并发控制的影响不同,从读未提交到可串行化,隔离级别越高,并发性能越低,但数据的一致性越好。 在实际应用中,系统...
6. **事务支持**:MySQL Cluster支持ACID(原子性、一致性、隔离性和持久性)事务,保证了数据的一致性和完整性。 7. **复制与复制模式**:MySQL Cluster使用多版本并发控制(MVCC)来实现数据复制,有同步和异步两...
本文大致介绍了TokuDB事务的隔离性实现原理,包括TokuDB的事务表示、分形树的LeafEntry的结构、MVCC的实现流程、多版本记录回收方式这些方面的内容。本文来自于微信听云,由火龙果软件Anna编辑、推荐。在安装MariaDB...
- **并发问题**:如脏读、不可重复读等问题可以通过适当的事务隔离级别来解决。 #### 七、初探延迟加载机制 - **延迟加载**:NHibernate支持延迟加载机制,即在实际需要数据时才从数据库加载,可以有效降低内存...
4. 基于Storm的报文系统初探 4.1 报文系统需求分析 报文系统需要处理高并发、业务隔离等需求,同时确保低延迟和高可用性。 4.2 原型系统设计 利用Storm的可扩展性和灵活性,设计了一个原型系统,通过定制Spout和...
4. Transaction:事务管理,控制一组操作的原子性、一致性、隔离性和持久性。 5. Query/Criteria API:提供SQL语句的面向对象表示,用于执行查询。 三、第一映射:对象关系映射 在Hibernate中,对象关系映射是通过...
- **上下文隔离**: 如何设置上下文之间的隔离,以防止数据竞争。 - **数据合并**: 如何将一个上下文中更改的数据合并到另一个上下文中。 **4. 高级主题** - **谓词** - **谓词创建**: 如何根据条件创建谓词。 ...