JPA + Hibernate + MySQL Cluster 事务处理

jpa查询数据库时,默认会开启事务,当数据库采用master-slave的架构部署时,事务请求会默认达到master节点,这样会导致master节点的负载过高。下面是对这个问题的分析和处理。
首先,默认情况下jpa启动时,会和MySQL数据库产生如下交互:

SET NAMES utf8mb4
SET character_set_results = NULL
SET autocommit=1

autocommit=1,是应用向MySQL数据库发起自动提交设置。在自动提交模式下,所有的sql请求都会自动提交。

JpaRepository中定义了一些通用的数据库查询方法,比如:List<T> findAll()。这些方法,如果在具体的Repository对象中没有重写的话,默认jpa会使用SimpleJpaRepository类中对应方法的实现,处理相关逻辑。

SimpleJpaRepository类的定义上,有如下内容:

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> 

下图是运行时,对应方法的AOP chain:
在这里插入图片描述

Transactional(readOnly = true)的设置,会使得jpa在执行相应方法时,关闭autocommit,采用手动提交的方式执行,对应的请求包如下:

SET autocommit=0
select xxxx from xxx
commit
SET autocommit=1

由于此时关闭了自动提交,MySQL集群会使用master处理上述请求。然而事实上,这个事务中只包含了一条select语句,并没有任何更新操作。所以,可以不用开启事务处理,这样的话,请求就可以随机地达到master和slave中的任意节点,流量可以更均衡。

解决方法也很简单,在具体的Repository中重写对应方法,并增加@Transactional(propagation = Propagation.SUPPORTS),如下:

@Repository
public interface DataSourceRepository extends JpaRepository<DataSource, String> {
    @Transactional(propagation = Propagation.SUPPORTS)
    List<DataSource> findAll();
}

Propagation.SUPPORTS表示,如果当前请求是在事务中,则使用当前事务执行,如果不在事务中,则不开启新事务,直接处理。此时,jpa便只会发送一条select xxx from xxx的查询语句到MySQL数据库中。

	/**
	 * Support a current transaction, execute non-transactionally if none exists.
	 * Analogous to EJB transaction attribute of the same name.
	 * <p>Note: For transaction managers with transaction synchronization,
	 * {@code SUPPORTS} is slightly different from no transaction at all,
	 * as it defines a transaction scope that synchronization will apply for.
	 * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
	 * will be shared for the entire specified scope. Note that this depends on
	 * the actual synchronization configuration of the transaction manager.
	 * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
	 */
	SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镜悬xhs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值