世界热点!美团二面:Spring事务不生效的15种场景
大家好,我是田螺。
日常开发中,我们经常使用到spring事务。最近星球一位还有去美团面试,被问了这么一道面试题:Spring 事务在哪几种情况下会不生效?今天田螺哥跟大家聊聊,spring事务不生效的15种场景。
【资料图】
1. 你的service类没有被Spring管理//@Service (注释了@Service)public class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public void addTianLuo(TianLuo tianluo) { //保存tianluo实体数据库记录 tianLuoMapper.save(tianluo); //保存tianluo流水数据库记录 tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}事务不生效的原因:上面例子中,@Service注解注释之后,spring事务(@Transactional)没有生效,因为Spring事务是由AOP机制实现的,也就是说从Spring IOC容器获取bean时,Spring会为目标类创建代理,来支持事务的。但是@Service被注释后,你的service类都不是spring管理的,那怎么创建代理类来支持事务呢。解决方案:加上@Service注解。2.没有在Spring配置文件中启用事务管理器
@Configurationpublic class AppConfig { // 没有配置事务管理器}@Servicepublic class MyService { @Transactional public void doSomething() { // ... }}事务不生效的原因:没有在AppConfig中配置事务管理器,因此Spring无法创建事务代理对象,导致事务不生效。即使在MyService中添加了@Transactional注解,该方法也不会被Spring管理的事务代理拦截。解决方案:为了解决这个问题,应该在AppConfig中配置一个事务管器。例如:
@Configurationpublic class AppConfig { @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); }}@Servicepublic class MyService { @Transactional public void doSomething() { // ... }}
3. 事务方法被final、static关键字修饰如果是Spring Boot项目,它默认会自动配置事务管理器并开启事务支持。
@Servicepublic class TianLuoServiceImpl { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public final void addTianLuo(TianLuo tianluo) { //保存tianluo实体数据库记录 tianLuoMapper.save(tianluo); //保存tianluo流水数据库记录 tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}事务不生效的原因:如果一个方法被声明为final或者static,则该方法不能被子类重写,也就是说无法在该方法上进行动态代理,这会导致Spring无法生成事务代理对象来管理事务。解决方案:addTianLuo事务方法不要用final修饰或者static修饰。4. 同一个类中,方法内部调用
@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; public void addTianLuo(TianLuo tianluo){ // 调用内部的事务方法 this.executeAddTianLuo(tianluo); } @Transactional public void executeAddTianLuo(TianLuo tianluo) { tianLuoMapper.save(tianluo); tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}事务不生效的原因: 事务是通过Spring AOP代理来实现的,而在同一个类中,一个方法调用另一个方法时,调用方法直接调用目标方法的代码,而不是通过代理类进行调用。即以上代码,调用目标executeAddTianLuo方法不是通过代理类进行的,因此事务不生效。解决方案:可以新建多一个类,让这两个方法分开,分别在不同的类中。如下:
@Servicepublic class TianLuoExecuteServiceImpl implements TianLuoExecuteService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public void executeAddTianLuo(TianLuo tianluo) { tianLuoMapper.save(tianluo); tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}@Servicepublic class TianLuoAddServiceImpl implements TianLuoAddService { @Autowired private TianLuoExecuteService tianLuoExecuteService; public void addTianLuo(User user){ tianLuoExecuteService.executeAddTianLuo(user); }}
当然,有时候你也可以在该Service类中注入自己,或者通过AopContext.currentProxy()获取代理对象。
5.方法的访问权限不是public@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional private void addTianLuo(TianLuo tianluo) { tianLuoMapper.save(tianluo); tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}事务不生效的原因:spring事务方法addTianLuo的访问权限不是public,所以事务就不生效啦,因为Spring事务是由AOP机制实现的,AOP机制的本质就是动态代理,而代理的事务方法不是public的话,computeTransactionAttribute()就会返回null,也就是这时事务属性不存在了。大家可以看下AbstractFallbackTransactionAttributeSource的源码:解决方案:addTianLuo事务方法的访问权限修改为public。6. 数据库的存储引擎不支持事务
Spring事务的底层,还是依赖于数据库本身的事务支持。在MySQL中,MyISAM存储引擎是不支持事务的,InnoDB引擎才支持事务。因此开发阶段设计表的时候,确认你的选择的存储引擎是支持事务的。
7 .配置错误的 @Transactional 注解@Transactional(readOnly = true)public void updateUser(User user) { userDao.updateUser(user);}事务不生效的原因:虽然使用了@Transactional注解,但是注解中的readOnly=true属性指示这是一个只读事务,因此在更新User实体时会抛出异常。解决方案:将readOnly属性设置为false,或者移除了@Transactional注解中的readOnly属性。8.事务超时时间设置过短
@Transactional(timeout = 1)public void doSomething() { //...}事务不生效的原因:在上面的例子中,timeout属性被设置为1秒,这意味着如果事务在1秒内无法完成,则报事务超时了。9. 使用了错误的事务传播机制
@Servicepublic class TianLuoServiceImpl { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional(propagation = Propagation.NOT_SUPPORTED) public void doInsertTianluo(TianLuo tianluo) throws Exception { tianLuoMapper.save(tianluo); tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo)); }}事务不生效的原因:Propagation.NOT_SUPPORTED传播特性不支持事务。解决方案:选择正确的事务传播机制。
帮大家复习一下,Spring提供了七种事务传播机制。它们分别是:
REQUIRED(默认):如果当前存在一个事务,则加入该事务;否则,创建一个新事务。该传播级别表示方法必须在事务中执行。SUPPORTS:如果当前存在一个事务,则加入该事务;否则,以非事务的方式继续执行。MANDATORY:如果当前存在一个事务,则加入该事务;否则,抛出异常。REQUIRES_NEW:创建一个新的事务,并且如果存在一个事务,则将该事务挂起。NOT_SUPPORTED:以非事务方式执行操作,如果当前存在一个事务,则将该事务挂起。NEVER:以非事务方式执行操作,如果当前存在一个事务,则抛出异常。NESTED:如果当前存在一个事务,则在嵌套事务内执行。如果没有事务,则按REQUIRED传播级别执行。嵌套事务是外部事务的一部分,可以在外部事务提交或回滚时部分提交或回滚。10. rollbackFor属性配置错误@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional(rollbackFor = Error.class) public void addTianLuo(TianLuo tianluo) { //保存tianluo数据库记录 tianLuoMapper.save(tianluo); //保存tianluo流水数据库记录 tianLuoFlowMapper.saveFlow(tianluo); //模拟异常抛出 throw new Exception(); }}事务不生效的原因: 其实rollbackFor属性指定的异常必须是Throwable或者其子类。默认情况下,RuntimeException和Error两种异常都是会自动回滚的。但是因为以上的代码例子,指定了rollbackFor = Error.class,但是抛出的异常又是Exception,而Exception和Error没有任何什么继承关系,因此事务就不生效。
大家可以看一下Transactional注解源码哈:
解决方案:rollbackFor属性指定的异常与抛出的异常匹配。11.事务注解被覆盖导致事务失效public interface MyRepository { @Transactional void save(String data);}public class MyRepositoryImpl implements MyRepository { @Override public void save(String data) { // 数据库操作 }}public class MyService { @Autowired private MyRepository myRepository; @Transactional public void doSomething(String data) { myRepository.save(data); }}public class MyTianluoService extends MyService { @Transactional(propagation = Propagation.REQUIRES_NEW) public void doSomething(String data) { super.doSomething(data); }}事务失效的原因:MyTianluoService是MyService的子类,并且覆盖了doSomething()方法。在该方法中,使用了不同的传播行为(REQUIRES_NEW)来覆盖父类的@Transactional注解。在这种情况下,当调用MyTianluoService的doSomething()方法时,由于子类方法中的注解覆盖了父类的注解,Spring框架将不会在父类的方法中启动事务。因此,当MyRepository的save()方法被调用时,事务将不会被启动,也不会回滚。这将导致数据不一致的问题,因为在MyRepository的save()方法中进行的数据库操作将不会回滚。12.嵌套事务的坑
@Servicepublic class TianLuoServiceInOutService { @Autowired private TianLuoFlowService tianLuoFlowService; @Autowired private TianLuoMapper tianLuoMapper; @Transactional public void addTianLuo(TianLuo tianluo) throws Exception { tianLuoMapper.save(tianluo); tianLuoFlowService.saveFlow(tianluo); }}@Servicepublic class TianLuoFlowService { @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional(propagation = Propagation.NESTED) public void saveFlow(TianLuo tianLuo) { tianLuoFlowMapper.save(tianLuo); throw new RuntimeException(); }}
以上代码使用了嵌套事务,如果saveFlow出现运行时异常,会继续往上抛,到外层addTianLuo的方法,导致tianLuoMapper.save也会回滚啦。如果不想因为被内部嵌套的事务影响,可以用try-catch包住,如下:
@Transactional public void addTianLuo(TianLuo tianluo) throws Exception { tianLuoMapper.save(tianluo); try { tianLuoFlowService.saveFlow(tianluo); } catch (Exception e) { log.error("save tian luo flow fail,message:{}",e.getMessage()); } }13. 事务多线程调用
@Servicepublic class TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowService tianLuoFlowService; @Transactional public void addTianLuo(TianLuo tianluo) { //保存tianluo数据库记录 tianLuoMapper.save(tianluo); //多线程调用 new Thread(() -> { tianLuoFlowService.saveFlow(tianluo); }).start(); }}@Servicepublic class TianLuoFlowService { @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public void save(TianLuo tianLuo) { tianLuoFlowMapper.saveFlow(tianLuo); }}事务不生效原因:这是因为Spring事务是基于线程绑定的,每个线程都有自己的事务上下文,而多线程环境下可能会存在多个线程共享同一个事务上下文的情况,导致事务不生效。Spring事务管理器通过使用线程本地变量(ThreadLocal)来实现线程安全。大家有兴趣的话,可以去看下源码哈.
在Spring事务管理器中,通过TransactionSynchronizationManager类来管理事务上下文。TransactionSynchronizationManager内部维护了一个ThreadLocal对象,用来存储当前线程的事务上下文。在事务开始时,TransactionSynchronizationManager会将事务上下文绑定到当前线程的ThreadLocal对象中,当事务结束时,TransactionSynchronizationManager会将事务上下文从ThreadLocal对象中移除。
14.异常被捕获并处理了,没有重新抛出@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public void addTianLuo(TianLuo tianluo) { try { //保存tianluo数据库记录 tianLuoMapper.save(tianluo); //保存tianluo flow数据库记录 tianLuoFlowMapper.saveFlow(tianluo); } catch (Exception e) { log.error("add TianLuo error,id:{},message:{}", tianluo.getId(),e.getMessage()); } }}事务不生效的原因: 事务中的异常已经被业务代码捕获并处理,而没有被正确地传播回事务管理器,事务将无法回滚。我们可以从spring源码(TransactionAspectSupport这个类)中找到答案:
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean { //这方法会省略部分代码,只留关键代码哈 @Nullable protected Object invokeWithinTransaction(Method method, @Nullable Class> targetClass, final InvocationCallback invocation) throws Throwable { if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) { TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification); Object retVal; try { //Spring AOP中MethodInterceptor接口的一个方法,它允许拦截器在执行被代理方法之前和之后执行额外的逻辑。 retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { //用于在发生异常时完成事务(如果Spring catch不到对应的异常的话,就不会进入回滚事务的逻辑) completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } //用于在方法正常返回后提交事务。 commitTransactionAfterReturning(txInfo); return retVal; }}
解决方案:在spring事务方法中,当我们使用了try-catch,如果catch住异常,记录完异常日志什么的,一定要重新把异常抛出来,正例如下:在invokeWithinTransaction方法中,当Springcatch到Throwable异常的时候,就会调用completeTransactionAfterThrowing()方法进行事务回滚的逻辑。但是,在TianLuoServiceImpl类的spring事务方法addTianLuo中,直接把异常catch住了,并没有重新throw出来,因此Spring自然就catch不到异常啦,因此事务回滚的逻辑就不会执行,事务就失效了。
@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional(rollbackFor = Exception.class) public void addTianLuo(TianLuo tianluo) { try { //保存tianluo数据库记录 tianLuoMapper.save(tianluo); //保存tianluo flow数据库记录 tianLuoFlowMapper.saveFlow(tianluo); } catch (Exception e) { log.error("add TianLuo error,id:{},message:{}", tianluo.getId(),e.getMessage()); throw e; } }}15. 手动抛了别的异常
@Servicepublic class TianLuoServiceImpl implements TianLuoService { @Autowired private TianLuoMapper tianLuoMapper; @Autowired private TianLuoFlowMapper tianLuoFlowMapper; @Transactional public void addTianLuo(TianLuo tianluo) throws Exception { //保存tianluo数据库记录 tianLuoMapper.save(tianluo); //保存tianluo流水数据库记录 tianLuoFlowMapper.saveFlow(tianluo); throw new Exception(); }}失效的原因:上面的代码例子中,手动抛了Exception异常,但是是不会回滚的,因为Spring默认只处理RuntimeException和Error,对于普通的Exception不会回滚,除非,用rollbackFor属性指定配置。解决方案:添加属性配置@Transactional(rollbackFor = Exception.class)。
注解为事务范围的方法中,事务的回滚仅仅对于unchecked的异常有效。对于checked异常无效。也就是说事务回滚仅仅发生在,出现RuntimeException或Error的时候。通俗一点就是:代码中出现的空指针等异常,会被回滚。而文件读写、网络超时问题等,spring就没法回滚了。
标签:
- 黄山提升政府采购透明度 助力实体经济持续健康稳定发展
- 1-2月黄山新签“双招双引”项目103个 总投资额139.7亿元
- 池州海关共签发RCEP原产地证书22份 签证金额92.7万美元
- 宿州泗县深入推进文旅融合发展 擦亮城市品牌
- 河北工业生产平稳开局 固定资产投资较快增长
- 昆明西山区深入实施人才强区战略 建立健全招商招才引资并轨新模式
- 2月唐山新建商品住宅销售价格与上月持平 同比下降0.8%
- 去年河北电子信息产业实现主营业务收入2367.7亿元 同比增长22.4%
- 绥化望奎以工业化思维为引领 推动肉类加工制造产业腾飞
- 绥化市监局推出多项举措 大力促进有机产品产业发展
- 半路出家无心插柳 杭州西湖区“菌菇宝宝”变废为宝
- 温州鹿城区藤桥主打藤桥熏鸡 近两年销售额年均增长20%以上
- 1-2月安徽限额以上消费品零售额1030.4亿元 同比增长10.4%
- 2021年合肥市茶园面积13.6万亩 产值176350万元
- 淡季不忘引流 京郊民宿市场将很快迎来回暖
- 郴州安仁文旅项目集中开工 总投资1000万元
- 江苏服务业继续保持发展强劲势头 为高质量发展提供有力支撑
- 黄山休宁经开区摸排基础设施项目17个 计划总投资29709万元
- 前两个月宣城出口31亿元 增长34.4%
- 滁州凤阳2021年共接待游客225万人次 旅游综合收入20.25亿元
- 1-2月宿州市民间投资同比增长19.2% 居全省第3位
- 宿州严格审核把关 抢抓发行地方政府专项债券政策机遇
- 1-2月亳州市进出口总值5.5亿元 同比下降17.4%
- 合肥:弘扬茶文化 初步形成一条生态发展之路
- 合肥:建成“数字中国”领先城市 推进城市数字化转型
- 甘肃再续“艾黎情”:探职业教育德技并修
- 【城市守望者】致敬抗“疫”一线的“拆弹专家”
- 浙江绍兴越城区核酸检测结果公布 除1例阳性外其余均为阴性
- 内地首例奥密克戎变异株感染者身体状况如何?来自哪里?专家解读→
- 对变异病毒已有准备!关于中国新冠药物,钟南山发声→
- 江苏睢宁小网格大担当 织就乡村振兴“幸福网”
- 改造老旧小区 共享幸福生活
- 天津静海:群众在哪里,文明实践就延伸到哪里
- 齐齐哈尔:初步判断疫情感染来源为接触新冠病毒污染环境和物品
- 重庆大竹林派出所副所长因对群众态度简单粗暴被停职
- 黑龙江讷河病例感染源初步判断为新冠病毒污染的环境和物品
- 致敬2021
- 浙江瑞安民警捐献造血干细胞:14年前的心愿终将如愿
- “考研房”涨价离谱 律师:借机宰客有违市场伦理
- 广州白云机场:14天内有东莞旅居史的旅客须凭48小时核酸阴性证明乘机
- 浙江绍兴本轮疫情已报告确诊病例145例 无症状感染者1例
- 福建龙岩一男子和前妻斗气 扛着126斤硬币到法院“还钱”
- 重庆这座立交酷似“悟空” 走红 设计师揭秘(图)
- 青海警方破获特大电诈案 涉案流水高达1.7亿
- 云南新增境外输入确诊病例3例
- 黑龙江讷河市5名核酸阳性人员流调溯源:接触被新冠病毒污染的环境和物品
- 男子爱上女主播 假扮女主播闺蜜教其他男粉丝刷单
- 广西三市警方联手破获毒品案 全链条摧毁跨境贩毒团伙
- 广东东莞发现2例无症状感染者,部分镇今起全员筛查
- 从百二秦关到闻道凯旋 一个殉职医生最后的朋友圈
- 浙江发补充说明:三地铁路出行政策随风险等级同步调整
- 内蒙古新增本土确诊病例5例 均在呼伦贝尔满洲里市
- 陕西新增本土确诊病例1例 系隔离酒店工作人员
- 31省份新增新冠肺炎确诊病例76例 其中本土51例
- 浙江新增新冠肺炎确诊病例45例 其中本土44例
- 技能就是财富 技工也是人才
- 黑龙江新增本土确诊病例1例、本土无症状感染者4例
- 冷空气“调休”!我国大部陆续迎回暖 中东部雨雪稀少
- 华北黄淮等地大气扩散条件转差 冷空气将影响中东部
- 别误读了野猪或将不再是“三有”动物
- 您的ETC已到期?当心这个诈骗短信!
- 对回家的“宝贝”少一些关注,也是一种帮助
- 升温!北京今日阳光在线 最高气温将升至8℃
- 那年今日 | 一张漫画涨知识之12月14日
- 40岁男子一觉醒来突然听不见了 原因是……
- 本年度星空压轴大赏上演 双子座流星雨观赏地图来了
- 广东东莞大朗镇报告2例新冠肺炎无症状感染者
- 商丘4885份被盗出生证去哪了?10年“悬案”引关注
- 浙江海宁警方通报国家公祭日女子穿和服逛街
- 厨艺不精调料凑?懒人调料:年轻人的“下厨神器”
- “您的ETC已到期?”警方提醒:当心这个诈骗短信
- “网红”局长的热度 自述:走红后我就没有周末了
- 寻回被拐10年的儿子后又送走 儿子:害我没家了
- 小城里的三张面孔和警号301137
- 倡导“就地过年”,需因地制宜科学防疫
- 别用“入乡随俗”为星巴克找借口
- 北京地铁14号线年底全线贯通运营
- 天津市从入境人员中检出奥密克戎变异株
- “外滩活地图”黄俊:一个不想出圈的段子手交警
- 寻找一双儿女的25年
- 无锡市场监管部门责成星巴克涉事门店停业整改
- 海岛警事:为了一座岛和2900平方公里的海
- 北京民警宏福苑抗疫26天:“今夜我和雪花一起出发”
- 星巴克的“金标准”缘何败给了“潜规则”
- 患者被低价药“惊呆”的场面应该更多些
- 影视剧“超前点评”不止是“低级错误”
- “南昌鹦鹉案”下发不起诉决定书 网店上架费氏牡丹鹦鹉被拒
- 河南商丘4885份出生医学证明被盗始末追踪
- 绍兴市病例62-109活动轨迹公布
- 12月7日以来,杭州累计报告新冠肺炎确诊病例19例
- 浙江绍兴新增确诊病例37例 上虞区占36例
- 河南高院对张成功案作出死刑判决
- 四川一滑雪场停电游客被困索道 官方回应
- 浙江绍兴越城区新增1例新冠肺炎确诊病例 当地对防控区域划分进行调整
- 中国内地首次检出新冠病毒奥密克戎变异株
- 知网除了涉及著作权纠纷,是否涉嫌违反《反垄断法》?
- 浙江绍兴越城区新增1例新冠肺炎确诊病例
- 四川眉山千箱柑橘送往呼和浩特市抗疫一线
- 两名青年男女探险三亚落笔洞遗址被困沼泽 消防成功救援
- 中国地理学大会在福州发布《中国地理学界碳中和科技行动福州宣言》
广告
广告
- 世界热点!美团二面:Spring事务不生效的15种场景
- 天龙二号遥一运载火箭发射成功 焦点热文
- 马英九一行参访长沙铁建重工
- 回来了!我国最北省份成“候鸟天堂”-焦点速递
- 普惠金融-小微指数发布 小微企业融资“获得感”提升
- 快报:三峡原文及注释_三峡翻译和原文一句一翻译
- 国家体育总局党组成员、副局长杜兆才接受中央纪委国家监委纪律审查和监察调查_全球即时
- 当前报道:男方和女方生育保险报销的区别是什么,女职工生育保险怎么报销?
- 银保监会:开展人寿保险与长期护理保险责任转换业务试点
- 神级强者在都市笔趣阁_神级强者在都市最新章|环球快消息
- 对比:2022年,美国对韩国出口石油37万桶/日,对印度、中国多少?
- 澳优去年营收近78亿,佳贝艾特下半年恢复双位数增长,穿越行业周期开新局 全球快播
- 环球热门:保鲜层结冰怎么办_冰箱保鲜层结冰的方法
- 世界快资讯:QG痛失冠军,伪装三次梦碎总决赛,网友:转会也难改没有冠军命
- 自己建了网站要怎么推广_网站要怎么推广 当前热文
- 江南集团于全:北京楼市稳步前进,对购房者更有利-最新消息
- 普京免去俄罗斯驻拉脱维亚和爱沙尼亚大使的职务
- 全球微头条丨人民网评:“五个一百”,奋进中国迸发澎湃活力
- 全球观热点:桓台县邢家中学举行廉洁文化建设主题宣讲活动
- iPhone15Pro放弃静音按键,取消了实体按键的设计?-独家