Spring事务之只读

定义

从设置的时间点(时间点beta)开始到事务结束的过程中,该事务将看不见其他事务所提交的数据,即查询中不会出现别人在beta之后提交的数据。
如果一个事务只对数据库执行读操作,那么该数据库就可能利用那个事务的只读特性,采取某些优化措施。通过把一个事务声明为只读,可以给后端数据库一个机会来应用那些它认为合适的优化措施。由于只读的优化措施是在一个事务启动时由后端数据库实施的, 因此,只有对于那些具有可能启动一个新事务的传播行为(PROPAGATION_REQUIRES_NEW、PROPAGATION_REQUIRED、 ROPAGATION_NESTED)的方法来说,将事务声明为只读才有意义

网上的各种资料里众说纷纭:
“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。(但是我尝试了,mysql数据库设置只读,做添加数据确实会报异常)

应用场合

对于一个函数,如果执行的只是单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;如果执行多条查询语句,例如统计查询,报表查询等,则多条查询SQL必须保证整体的读一致性;否则,若在前后两条查询SQL执行的间隙,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的情况,此时,应该启用事务支持。注意,是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务。

如何设置

对于只读查询,可以指定事务类型为readonly,即只读事务
由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。指定只读事务的办法如下:

  • 在JDBC中,令connection.setReadOnly(true);
  • 在Hibernate中,令 session.setFlushMode(FlushMode.NEVER);
    此时,Hibernate也会为只读事务提供Session方面的一些优化手段。
  • 在Spring的Hibernate封装中,在bean配置文件中,prop属性增加“readOnly”;
  • 使用注解 @Transactional(readOnly=true)
    在将事务设置成只读后,相当于将数据库设置成只读数据库,此时若要进行写的操作,会出现错误。

其他知识

1.readonly并不是所有数据库都支持的,不同的数据库下会有不同的结果。
2.设置了readonly后,connection都会被赋予readonly,效果取决于数据库的实现。
3.在ORM中,设置了readonly会赋予一些额外的优化,例如在Hibernate中,会被禁止flush等
4.在oracle下测试,发现不支持readOnly,也就是不论Connection里的readOnly属性是true还是false均不影响SQL的增删改查;
5.在mysql下测试,发现支持readOnly,设置为true时,只能查询,若增删改会异常:
6.readOnly对oracle不生效是因为:

1 con.setReadOnly(true);
2 con.setAutoCommit(false);

autoCommit与readOlny赋值的顺序对其有影响,readonly在后则生效,readolny在前是无效的可进行insert/update/delete操作。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,只读事务和读写事务是两种不同的事务类型。只读事务用于查询操作,不允许对数据库进行修改操作,而读写事务则可以进行查询和修改操作。 如果需要在只读事务中添加写操作,我们可以通过以下步骤进行修改: 1. 确定是否真正需要在只读事务中进行写操作。由于只读事务的设计初衷是为了提高查询性能和并发度,将写操作加入其中可能会降低性能。 2. 在Spring事务管理配置文件(如XML配置文件或注解配置类)中,将只读事务的isolation属性设置为默认级别或其他适当的级别,以允许读写操作。例如,将isolation属性设置为READ_COMMITTED或其他适合的级别。 3. 在需要添加写操作的方法上,添加@Transactional注解或将@Transactional注解的只读属性设为false,这将将方法标记为读写事务。 4. 在方法中进行必要的修改操作,并确保在对数据库进行写操作之前,正确地处理事务的提交和回滚。 需要注意的是,在只读事务中添加写操作可能会引发一些问题。如果修改操作发生异常,只读事务默认情况下将回滚事务。因此,在添加写操作时,必须确保在出现异常时正确处理事务的回滚和异常处理。 总之,如果需要在Spring只读事务中添加写操作,可以通过调整事务的隔离级别和在方法上添加@Transactional注解来实现。但是需要注意在这个过程中,适当处理事务的提交和回滚来确保数据的一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值