设置事务隔离性级别
1)幻读:事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录;
2)不可重复读取:事务1读取记录时,事务2更新了记录并提交,事务1再次读取时可以看到事务2修改后的记录;
3)脏读:事务1更新了记录,但没有提交,事务2读取了更新后的行,然后事务T1回滚,现在T2读取无效。
READ UNCOMMITTED:幻读,不可重复读和脏读均允许;
READ COMMITTED:允许幻读和不可重复读,但不允许脏读;
REPEATABLE READ:允许幻读,但不允许不可重复读和脏读;
SERIALIZABLE:幻读,不可重复读和脏读都不允许
ORACLE默认的是 READ COMMITTED SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED|READUNCOMMITTED|REPEATABLE READ;
spring 中一共定义了六种事务传播属性
PROPAGATION_REQUIRED --支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED --如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJBCMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 SavepointAPI提供嵌套事务行为(如Spring的DataSourceTransactionManager)
Spring @Transactional属性说明
Propagation |
事务传播行为 |
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 |
Isolation |
事务隔离级别 |
@Transactional(isolation = Isolation.READ_UNCOMMITTED)读取未提交数据(会出现脏读, 不可重复读) 基本不使用 @Transactional(isolation = Isolation.READ_COMMITTED)读取已提交数据(会出现不可重复读和幻读) @Transactional(isolation = Isolation.REPEATABLE_READ)可重复读(会出现幻读) @Transactional(isolation = Isolation.SERIALIZABLE)串行化 |
Spring事务的传播行为
在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。
Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked
如果遇到checked意外就不回滚。
如何改变默认规则:
1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。
spring——@Transactional事务不管理jdbc,所以要自己把jdbc事务回滚。
下面给出了回滚JDBC事务的代码示例:
- public void processT(String orders) {
- Context initCtx = new InitialContext();
- javax.sql.DataSource ds = javax.sql.DataSource)initCtx.lookup
- (“java:comp/env/jdbc/OrdersDB”);
- java.sql.Connection conn = ds.getConnection();
- try {
- conn.setAutoCommit( false ); //更改JDBC事务的默认提交方式
- orderNo = createOrder( orders );
- updateOrderStatus(orderNo, “orders created”);
- conn.commit(); //提交JDBC事务
- } catch ( Exception e ){
- try {
- conn.rollback(); //回滚sJDBC事务
- throw new EJBException(“事务回滚: “ + e.getMessage());
- } catch ( SQLException sqle ){
- throw new EJBException(“出现SQL操作错误: “ + sqle.getMessage());
- }
- }
- }
下面给出了JTA事务代码示例:
- public void processOrder(String orderMessage) {
- UserTransaction transaction = mySessionContext.getUserTransaction(); //获得JTA事务
- try {
- transaction.begin(); //开始JTA事务
- orderNo = sendOrder(orderMessage);
- updateOrderStatus(orderNo, “order sent”);
- transaction.commit(); //提交JTA事务
- } catch (Exception e){
- try {
- transaction.rollback(); //回滚JTA事务
- } catch (SystemException se){
- se.printStackTrace();
- }
- throw new EJBException(“事务回滚: “ + e.getMessage());
- }
- }
在整个方法运行前就不会开启事务
还可以加上:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),这样就做成一个只读事务,可以提高效率。
各种属性的意义:
REQUIRED:业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。
NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。
REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。
MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。
SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。
NEVER:该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务 拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。
Isolation Level(事务隔离等级)
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。
我们知道并行可以提高数据库的吞吐量和效率,但是并不是所有的并发事务都可以并发运行。
我们首先说并发中可能发生的3中不讨人喜欢的事情
1: Dirty reads--读脏数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
2: non-repeatable reads--数据不可重复读。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成 200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。
3: phantom reads--幻象读数据,这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
Dirty reads non-repeatable reads phantom reads
Serializable 不会 不会 不会
REPEATABLE READ 不会 不会 会
READ COMMITTED 不会 会 会
Read Uncommitted 会 会 会
readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。
相关推荐
Spring事务详细讲解 在 Spring 框架中,事务管理扮演着非常重要的角色。Spring 声明式事务让我们从复杂的事务处理中得到解脱,使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要...
例如,在Java程序中可以使用Spring框架提供的声明式事务管理来控制事务的行为,从而避免脏读、不可重复读和幻读等问题的发生。 1. **基于元数据的Spring声明式事务**: - Spring框架提供了`@Transactional`注解,...
每种隔离级别都有其特定的并发控制策略,以防止脏读、不可重复读和幻读等并发问题。 "spring事务操作主要对象.png"可能展示了Spring事务管理的关键组件,如TransactionDefinition(定义事务属性)、...
5. **Isolation.SERIALIZABLE**:最高的隔离级别,完全避免了脏读、不可重复读和幻读,但性能最差,因为需要锁定事务涉及的所有行。 在实际应用中,开发者需要根据业务需求来选择合适的事务传播属性和隔离级别,以...
- SERIALIZABLE:最高级别,防止脏读、不可重复读和幻读,但性能最差。 - DEFAULT:根据数据库的默认隔离级别。 ### 3. 使用Spring JDBC与事务管理 Spring JDBC模块提供了`JdbcTemplate`和`SimpleJdbcInsert`等...
这些传播行为的选择对事务的边界有着直接的影响,合理的设置可以避免并发问题,如脏读、不可重复读和幻读等。在设计和实现业务逻辑时,根据方法的业务性质选择合适的事务传播属性,可以提高系统的稳定性和性能。 ...
- 最高的隔离级别,确保事务顺序执行,可以防止所有并发问题,包括脏读、不可重复读和幻读,但性能开销较大。 了解并合理设置事务的传播特性和隔离级别对于构建健壮的事务处理机制至关重要。正确配置可以确保数据...
- `READ_UNCOMMITTED`: 最低级别,允许脏读、不可重复读和幻读。 - `READ_COMMITTED`: 防止脏读,但可能出现不可重复读和幻读。 - `REPEATABLE_READ`: 防止脏读和不可重复读,但可能出现幻读。 - `SERIALIZABLE`...
本文将详细解析Spring事务属性中的四个关键元素:事务隔离级别、事务传播行为、事务超时时间以及事务是否只读。 首先,我们来探讨事务隔离级别。事务隔离级别是解决并发事务可能导致的问题,如脏读、不可重复读和幻...
5. **ISOLATION_SERIALIZABLE**:最高隔离级别,完全避免脏读、不可重复读和幻读。 通过上述内容,我们可以看出Spring的事务管理机制是基于AOP和底层数据库支持的,它极大地简化了事务处理的复杂度,并提供了灵活的...
Spring事务还支持多种隔离级别,包括READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE,不同的隔离级别可以防止脏读、不可重复读、幻读等并发问题,但也会对性能产生影响,因此需要根据实际需求...
- **隔离级别**:Spring支持数据库事务的四种隔离级别,包括读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。这些隔离级别决定了并发环境中事务...
4. `ISOLATION_REPEATABLE_READ`:防止脏读和不可重复读,但可能有幻读现象,即在不同事务中,相同查询结果集可能不同。 5. `ISOLATION_SERIALIZABLE`:最高级别的隔离,避免了所有上述问题,但性能开销较大,因为...
根据业务需求,选择合适的隔离级别可以避免脏读、不可重复读和幻读等问题。 在Spring的事务管理中,还有回滚规则和异常处理。默认情况下,运行时的检查异常(checked exception)不会导致事务回滚,而未检查异常...
- 事务隔离级别:定义了事务的隔离水平,例如读未提交、读提交、可重复读和串行化。 - 只读事务:通过设置事务为只读模式,可以提高事务的性能,尤其是对于那些只进行数据读取操作的事务。 - 超时设置:可以为事务...
- REPEATABLE_READ:可重复读,防止脏读和不可重复读,但可能发生幻读。 - SERIALIZABLE:序列化,最高级别,防止所有问题,但性能最差。 6. **Spring事务的局限性**: Spring事务管理对JDBC、Hibernate、...
4. **事务隔离级别** - 包括READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE,定义了不同事务间的可见性和并发控制策略,防止脏读、不可重复读和幻读等问题。 5. **事务异常回滚规则** - 默认...
- `READ_UNCOMMITTED`:最低级别,可能导致脏读、不可重复读和幻读。 - `READ_COMMITTED`:防止脏读,但可能产生不可重复读和幻读。 - `REPEATABLE_READ`:防止脏读和不可重复读,但可能出现幻读。 - `...