Mycat读写分离可以看 mycat读写分离方案一
1.application.properties配置连接
只要连接上mycat就可以和正常的mysql连接一样
spring.datasource.url = jdbc:mysql://127.0.0.1:8066/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC
spring.datasource.primary.username = test_write
spring.datasource.primary.password = abcd12345678@
spring.datasource.driverClassName = com.mysql.jdbc.Driver
2.去除查询的readOnle事务
@Aspect @Configuration public class TxAdviceInterceptor { private static final int TX_METHOD_TIMEOUT = 20; //所有的mysqlJPA接口,排除掉mongodb的 private static final String AOP_POINTCUT_EXPRESSION = "execution(* com..*Jpa*.*(..)) && !execution(* com..mongodb..*Jpa*.*(..))"; @Autowired private PlatformTransactionManager transactionManager; @Bean public TransactionInterceptor txAdvice() { NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource(); /*只读事务,不做更新操作*/ RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute(); readOnlyTx.setReadOnly(true); readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED ); /*当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务*/ RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(); requiredTx.setRollbackRules( Collections.singletonList(new RollbackRuleAttribute(Exception.class))); requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); requiredTx.setTimeout(TX_METHOD_TIMEOUT); Map<String, TransactionAttribute> txMap = new HashMap<>(); txMap.put("add*", requiredTx); txMap.put("save*", requiredTx); txMap.put("insert*", requiredTx); txMap.put("update*", requiredTx); txMap.put("delete*", requiredTx); //读取的统一去除事务,不然mycat会走写库 // txMap.put("get*", readOnlyTx); // txMap.put("query*", readOnlyTx); // txMap.put("find*", readOnlyTx); source.setNameMap( txMap ); TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source); return txAdvice; } @Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice()); }
3.测试代码
Controller
@Autowired private AccountJpa accountJpa; /** * http://localhost:12000/public/getAccounts * @return * @throws Exception */ @RequestMapping(value = "/getAccounts", method = RequestMethod.GET ) public Msg getAccounts() throws Exception{ return Msg.MsgSuccess(accountJpa.findAll()); }
Entity
import com.cloud.core.common.entity.BaseEntity; import com.cloud.core.module.wechat.entity.WeChat; import lombok.Data; import org.springframework.context.annotation.Scope; import javax.persistence.*; import javax.validation.constraints.NotBlank; import java.io.Serializable; @Entity @Table(name = "account",uniqueConstraints = { @UniqueConstraint(columnNames = { "account","is_delete" }) } ) @Scope(value = "prototype") @Data public class Account extends BaseEntity implements Serializable { /** * 账号 */ @Column(name = "account") @NotBlank(message = "请填写账号") private String account; /** * 密码 */ @Column(name = "password") @NotBlank(message = "请填写密码") private String password; }
AccountJpa
import com.cloud.core.module.test.entity.Account; import com.cloud.core.module.vote.entity.Operator; import org.springframework.data.jpa.repository.JpaRepository; public interface AccountJpa extends JpaRepository<Account, String> { }
测试查询是否走读库
测试接口可以看到,一直读到是读库的数据
修改的正常处理就可以了,我就不再测试了。也这样正常使用事务,mycat是支持事务。(测试写的时候记得把从库数据改回和主库一样,我是为了测试才这样改的,不是正规操作)
来源:oschina
链接:https://my.oschina.net/u/4039389/blog/3234716