[rent] 2019-02-22 18:09:41,751 ERROR [DubboServerHandler-172.20.30.57:20880-thread-18] com.company.rent.platform.service.dubbo.RentDubboExceptionHandler.aroudMethod(63) | dubbo service has a rentDubboException that is The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!.
上面这段错误是dubbo的接口的service在save时总数报错,而同样的接口在一般rest接口的service的save保存可以成功。
Connection is read-only. Queries leading to data modification are not allowed
当我解决dubbo的事务没有办法提交时,发现一般的rest的service的save保存一致提示上面的错误。
到此刻:一头两个大;
原因就是事务配置这块有问题,怎么搞呢?
为了调试dubbo接口顺便查找了dubbo如何本地调试,在reference中加入:url="dubbo://localhost:20881"
,就能解决。原本的dubbo2.5.3被我升级到了2.6.0。
搞了3天终于解决这两块问题,一定要记录一下此次踩的坑;
场景
把一个传统tomcat方式运行的项目改造成了springboot方式运行,需要重新配置数据源、事务、dubbo、spring、springmvc等等工作。
项目最终运行环境:springboot1.5.2\dubbo2.6.0\spring4.3.5\springdatajpa1.10.5。
最终代码配置
SpringApplication配置
@SpringBootApplication
@Import(SpringContextHolder.class)
@ComponentScan(basePackages = {"com.company"},excludeFilters = { @ComponentScan.Filter(value = Controller.class)})
@ServletComponentScan({"com.company.rent.platform"})
@PropertySource(value = "classpath:application.properties",ignoreResourceNotFound = true)
@ImportResource({"classpath:dubbo-consumer.xml","classpath:dubbo-producer.xml"})
@EnableTransactionManagement
public class RentApplication extends SpringBootServletInitializer {
static ConfigurableApplicationContext cac;
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(RentApplication.class);
}
public static void main(String[] args){
SpringApplication app = new SpringApplicationBuilder(RentApplication.class).build();
cac = app.run(args);
}
}
Dubbo消费者配置
<dubbo:application name="rent"/>
<dubbo:registry address="${dubbo.zookeeperAddress}" register="true"/>
<!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
<dubbo:annotation package="com.isesol"/>
<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
<!-- Rent引入平台基础服务 -->
<dubbo:reference id="jpushDubboService" interface="com.company.service.JpushDubboService"/>
<dubbo:reference id="jpushMsgService" interface="com.company.membercenter.dubbo.v2.service.JpushMsgService"/>
<dubbo:reference id="rentApplyService" interface="com.smtcl.iplatform.machinearchive.rentservices.IRentApplyService"/>
<dubbo:reference id="rentPlatformService" interface="com.company.factorycloud.dubbo.rent.IRentPaltformService"/>
<dubbo:reference id="memberCenterService" interface="com.company.service.MemberCenterService"/>
<dubbo:reference id="memberServiceV2" interface="com.company.membercenter.dubbo.v2.service.MemberService"/>
<dubbo:reference id="memberInfoServiceV2" interface="com.company.membercenter.dubbo.v2.service.MemberInfoService"/>
<dubbo:reference id="memberManagerService" interface="com.company.membercenter.dubbo.v2.service.MemberManagerService"/>
<dubbo:reference id="verifyCodeService" interface="com.company.membercenter.dubbo.v2.service.VerifyCodeService"/>
<dubbo:reference id="userOperateMemberService" interface="com.company.membercenter.dubbo.v2.service.UserOperateMemberService"/>
<dubbo:reference id="phoneNumRuleService" interface="com.company.membercenter.dubbo.v2.service.PhoneNumRuleService"/>
<dubbo:reference id="userCenterService" interface="com.company.service.UserCenterService"/>
<dubbo:reference id="iAuthService" interface="com.company.authority.api.service.IAuthService"/>
<dubbo:reference id="iButtonService" interface="com.company.authority.api.service.IButtonService"/>
<dubbo:reference id="iModuleService" interface="com.company.authority.api.service.IModuleService"/>
<dubbo:reference id="iOrgGroupService" interface="com.company.authority.api.service.IOrgGroupService"/>
<dubbo:reference id="iPageService" interface="com.company.authority.api.service.IPageService"/>
<dubbo:reference id="iRoleService" interface="com.company.authority.api.service.IRoleService"/>
<dubbo:reference id="iUserService" interface="com.company.authority.api.service.IUserService"/>
<dubbo:reference id="uploadTokenService" interface="com.company.support.service.UploadTokenService"/>
<dubbo:reference id="factoryService" interface="com.company.cngl.service.dubbo.IFactoryService"/>
<dubbo:reference id="tokenVerifyService" interface="com.company.service.lgn.TokenVerifyService"/>
<dubbo:reference interface="com.company.rent.service.IDemoService" url="dubbo://localhost:20881" check="false"></dubbo:reference>
Dubbo生产者配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- Rent 提供的服务 -->
<dubbo:service interface="com.company.rent.service.IRentMtService" ref="iRentMtService"/>
<dubbo:service interface="com.company.rent.service.IDemoService" ref="iDemoService"/>
<dubbo:service interface="com.company.rent.service.IRentCustomerService" ref="iRentCustomerService"/>
<dubbo:service interface="com.company.rent.service.IRentOrderService" ref="iRentOrderService"/>
<dubbo:service interface="com.company.rent.service.IRentCompanyService" ref="iRentCompanyService"/>
<dubbo:service interface="com.company.rent.service.IRentBillService" ref="iRentBillService"/>
<dubbo:service interface="com.company.rent.service.IRentContractService" ref="iRentContractService"/>
<dubbo:service interface="com.company.rent.service.IRentMtDataService" ref="iRentMtDataService"/>
</beans>
数据源及事务配置
/**
* 自定义数据源配置
* @author: Owen Jia
* @time: 2018/12/20 13:49
*/
@Configuration
@EnableJpaAuditing
@EnableJpaRepositories(basePackages = "com.isesol")
@EnableAspectJAutoProxy
public class DataSourceConfig {
@Value("${jdbc.driver}")
String driverClassName;
@Value("${jdbc.url}")
String url;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
@Value("${jdbc.pool.maxActive}")
int maxActive;
@Value("${jdbc.pool.initialSize}")
int initialSize;
@Value("${jdbc.pool.maxWait}")
int maxWait;
@Value("${jdbc.pool.minIdle}")
int minIdle;
@Bean(name = "dataSource",autowire = Autowire.BY_TYPE)
public DataSource initDurid() {
DruidDataSource druid = new DruidDataSource();
druid.setUrl(url);
druid.setDriverClassName(driverClassName);
druid.setUsername(username);
druid.setPassword(password);
try {
druid.setFilters("stat");
} catch (SQLException e) {
e.printStackTrace();
}
druid.setMaxActive(maxActive);
druid.setInitialSize(initialSize);
druid.setMaxWait(maxWait);
druid.setMinIdle(minIdle);
druid.setValidationQuery("select user()");
druid.setTimeBetweenEvictionRunsMillis(180000);
druid.setMinEvictableIdleTimeMillis(300000);
druid.setTestWhileIdle(true);
druid.setTestOnBorrow(true);
druid.setTestOnReturn(false);
//配置druid连接超时占用强制回收,owen jia at 20190211
druid.setRemoveAbandoned(true);
druid.setRemoveAbandonedTimeout(600);
druid.setLogAbandoned(true);
druid.setPoolPreparedStatements(true);
druid.setMaxOpenPreparedStatements(200);
druid.setProxyFilters(Lists.newArrayList(initLogFilter(),initStatFilter()));
return druid;
}
@Bean(name = "jdbcTemplate")
public JdbcTemplate initJdbcTemplate(){
return new JdbcTemplate(initDurid());
}
@Bean(name = "log-filter")
public Slf4jLogFilter initLogFilter(){
Slf4jLogFilter filter = new Slf4jLogFilter();
filter.setDataSourceLogEnabled(true);
filter.setConnectionLogEnabled(true);
filter.setResultSetLogEnabled(true);
filter.setStatementExecutableSqlLogEnable(true);
filter.setStatementLogEnabled(true);
return filter;
}
@Bean(name = "stat-filter")
public StatFilter initStatFilter(){
StatFilter statFilter = new StatFilter();
statFilter.setSlowSqlMillis(180000);
statFilter.setLogSlowSql(true);
statFilter.setMergeSql(true);
statFilter.setConnectionStackTraceEnable(true);
return statFilter;
}
@Value("${hibernate.hbm2ddl.auto}")
String hbm2ddlAuto;
@Value("${hibernate.show_sql}")
String showSql;
@Value("${hibernate.format_sql}")
String formatSql;
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean initFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(initDurid());
factoryBean.setJpaVendorAdapter(initHibernateJpaVendorAdapter());
factoryBean.setPersistenceUnitName("default");
factoryBean.setPackagesToScan("com.company.rent");
Properties jpaProp = new Properties();
jpaProp.setProperty("hibernate.hbm2ddl.auto",hbm2ddlAuto);
jpaProp.setProperty("hibernate.show_sql",showSql);
jpaProp.setProperty("hibernate.format_sql",formatSql);
jpaProp.setProperty("hibernate.physical_naming_strategy", ImprovedNamingStrategy.class.getName());
// Owen Jia at 20190211
//配置连接释放模式:after_statement 请求执行后释放,after_transaction 事务提交后释放,on_close session主动关闭释放
jpaProp.setProperty("hibernate.connection.release_mode","after_transaction");//"on_close"
factoryBean.setJpaProperties(jpaProp);
return factoryBean;
}
@Bean(name = "hibernateJpaVendorAdapter")
public HibernateJpaVendorAdapter initHibernateJpaVendorAdapter(){
HibernateJpaVendorAdapter jpaVendor = new HibernateJpaVendorAdapter();
jpaVendor.setDatabasePlatform(Hibernates.getDialect(initDurid()));
return jpaVendor;
}
@Bean(name = "transactionManager")
public JpaTransactionManager initJapTransactionM(){
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(initFactoryBean().getNativeEntityManagerFactory());
return jpaTransactionManager;
}
@Bean(name = "transactionTemplate")
public TransactionTemplate initTransactionTemplate(){
TransactionTemplate transactionTemplate = new TransactionTemplate();
transactionTemplate.setTransactionManager(initJapTransactionM());
return transactionTemplate;
}
}
Yaml文件配置,只给出相关特别配置,其他都是常规
debug=true
logging.config=classpath:log4j2.xml
spring.profiles.active=${ENV:dev}
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
server.context-path=/
server.port=8080
server.session.timeout=20
server.tomcat.uri-encoding=utf-8
作者:Owen Jia
推荐关注他的博客:Owen Blog,里面大量优质博文。