java 数据库 事务 只读_spring事务管理与查询是否需要事务以及可重复读的问题...

我们先来看下通常的spring配置:

上面的配置中增删改中用propagation="REQUIRED"和"REQUIRES_NEW",都是需要开启写事务的,应该每个人都知道,但查询是否需要开启事务呢?反正我在这之前,真的以为不用,也没必须开启。但今天研究了下mycat的读写分离,发现写事务里的读都走写库,这种做法是为了保证查询数据的一致性,也就是保证数据库的可重复读事务隔离性。

我们再看看上面的读配置:

其中tx里的默认传播性是propagation="REQUIRED" read-only默认为"false",默认可写的意思,也就是说上面的配置是有事务的,只是告诉数据库此事务没有需要更新的语句,事务只读,用spring这么久了,我才发现虽然配置了read-only="true",但上面的事务配置查询也是有事务的!

所以说查询也是需要开启事务的,以MySQL为例,这是为了这一组事务里的所有查询在Repeatable Read隔离级别下能做到一致性,也就是常说的可重复读。

举个例子,如果上面的读配置成无事务,如下:

那么就可能在一组查询中出现数据不致的问题,如:

public void getUserList(){

select count(*) from user_info

select * from user_info limit 0,10

}

如上我们service里有这么一个方法(事务切面定义的是service里的方法),用来分页查询的,当第一条查询出来count为6条数据时,正好有人删除了其中一条数据,因为getUserList()方法定义为无事务,下面这条语句查询用户数据查询出来就只有5条,造成了前后数据不一致,这违背了Repeatable Read隔离级别。我们也不希望用户看到这种情况。所以说为了保证可重复读,查询也是需要事务的,只不过为了优化数据查询,将read-only设为"true"。

另外,如果你的方法里或者说此次查询操作只有一个查询语句,那就没必要开启只读事务了,因为只有一个语句,没有一致性的问题,数据库默认可重复读的事务级别,也就是说spring里的事务配置,可以给这种方法配置成无事务,这样做会让你的查询性能提升很多,当然如果你的程序的查询密集型,并且不在意查询一致性的问题的话,一样可以设置成查询无事务,因为这么做相对于有只读事务的查询来说,性能可以提升3-4倍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值