当前位置: 首页 > news >正文

手机网站表单页面制作杭州有哪些性价比高的网站建设服务商

手机网站表单页面制作,杭州有哪些性价比高的网站建设服务商,域名服务器地址,四川省建设网站平台并发修改导致MVCC脏写问题 一、概要 1.1 业务场景 数据库表结构设计#xff1a; 一个主档数据#xff0c;通过一个字段#xff0c;逗号分隔的方式去关联其他明细信息的id。 如主档数据A#xff0c;有3条明细数据与A关联#xff0c;其id分别是1,2,3#xff0c;那么其存…并发修改导致MVCC脏写问题 一、概要 1.1 业务场景 数据库表结构设计 一个主档数据通过一个字段逗号分隔的方式去关联其他明细信息的id。 如主档数据A有3条明细数据与A关联其id分别是1,2,3那么其存储在关联字段的值为1,2,3。 操作场景 接口设计操作①根据id查询主档数据 ②获取主档数据关联的明细id ③更新主档明细id 入参主档id、明细id这里不传列表是因为相应参数需要返回相应的信息因此就涉及成这样了 在实际应用中可能需要涉及到批量新增的操作因此前端会出现某一时间点同时调用多次该接口导致MVCC脏写问题。 1.2 DEMO 初始化 MySQL中创建demo表 # 建表 CREATE TABLE test ( id INT(11) NOT NULL COMMENT 主档id, ids VARCHAR(255) DEFAULT NULL COMMENT 关联ids, PRIMARY KEY (id) ) ENGINEINNODB DEFAULT CHARSETutf8;建立相应的web三层架构controller、service、mapper controller RestController RequestMapping(/demo) public class democontroller {Resourceprivate demoService demoservice;GetMapping(/test)public void test(Long id, String relId) {demoservice.test(id, relId);}}service public interface demoService {void test(Long id, String relId); }service-实现类 Slf4j Service public class demoServiceImpl extends ServiceImplDemoMapper, Demo implements demoService {OverrideTransactional(rollbackFor Exception.class)public void test(Long id, String relId) {// 获取主档对象Demo demo getById(id);// 打印当前线程获取到的ids列表log.info(Thread Name:{}, before demo:{},Thread.currentThread().getName(), demo);// 获取当前关联明细idListString idsList Arrays.stream(demo.getIds().split(,)).collect(Collectors.toList());// 添加新的元素去重操作省略idsList.add(relId);// 更新关联字段demo.setIds(idsList.stream().collect(Collectors.joining(,)));// 打印当前线程获取到的ids列表log.info(Thread Name:{}, after demo:{},Thread.currentThread().getName(), demo);updateById(demo);} }mapper Mapper public interface DemoMapper extends BaseMapperDemo { }实体类 Data EqualsAndHashCode(callSuper true) TableName(test) public class Demo extends ModelDemo {TableId(value id, type IdType.ASSIGN_ID)private Integer id;private String ids;}1.3 问题复现 数据初始化 INSERT INTO study_test.test(id, ids) VALUES (1, 1);通过apifox开三个线程并发调用“/demo”接口入参如下所示id固定为1relId为一个整数值1-999随机数 调用结果如下所示 问题到此复现。 二、 原因分析 原因已经在标题中打出来了即MVCC的脏写问题当我们使用Transactional(rollbackFor Exception.class)注解后Spring 会为当前事务设置 MySQL 会话的事务隔离级别为MySQL默认隔离级别即RR可重复读。 我们在打个断点后通过apifox发起并发访问 在MySQL中通过select trx_state, trx_started, trx_mysql_thread_id, trx_query, trx_isolation_level from information_schema.innodb_trx;命令查看当前执行中且未提交的事务可以看到此时有三条事务正在运行中并且他们的隔离级别是可重复读RR 由于在RR隔离级别下访问数据即getById操作访问的数据是通过MVCC实现的快照读此时在并发访问的情况下可能三个事务查询到的结果都是一样的所以导致最后在更新的时候只出现了新增成功一个值。 三、解决 3.1 将隔离级别改成串行无效 一开始是这个想法因为串行级别下都是会加锁的因此通过改变Transactional参数Transactional(rollbackFor Exception.class, isolation Isolation.SERIALIZABLE)将事物隔离级别改成串行也许可以解决问题。 当我们并发调用该接口后发生报错即在尝试加锁的时候检测到了死锁 2024-12-16 23:59:48.615 ERROR 45800 --- [nio-6666-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DeadlockLoserDataAccessException: ### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ### The error may exist in com/example/mapper/DemoMapper.java (best guess) ### The error may involve com.example.mapper.DemoMapper.updateById-Inline ### The error occurred while setting parameters ### SQL: UPDATE test SET ids? WHERE id? ### Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction] with root cause打个断点将其中两个事物停在查询查找后更新操作前将其中一个操作停在更新操作后 通过命令select trx_state, trx_started, trx_mysql_thread_id, trx_query, trx_isolation_level from information_schema.innodb_trx;查看当前未提交的任务 可以看到有三个未提交事务其中一个在进行更新操作的时候发生了锁等待 通过命令 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;查看一下当前加锁情况 结果就是两个事务给数据加了S锁一个事务需要给更改记录加X锁同时前两个事物在后面也需要给数据加X锁造成了死锁。 注关于多线程并发访问打断点需要进行如下设置 3.2 开批量新增接口无效 开批量新增接口将需要关联的id通过一个接口传入而不是同时调用三次接口分别传入来解决该问题但是如果在并发场景下还是会出关联id丢失的问题。 3.3 乐观锁 (无效) 相关乐观锁实现可以参考mybatis-plus官网的文档https://baomidou.com/plugins/optimistic-locker/。乐观锁在我理解上就是做版本控制每次更新操作都要对版本进行验证 这里直接采用mybatis-plus提供的配置方式进行测试 配置文件 Configuration public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;} } 实体类 Data EqualsAndHashCode(callSuper true) TableName(test) public class Demo extends ModelDemo {TableId(value id, type IdType.ASSIGN_ID)private Integer id;private String ids;Versionprivate Integer version;}在数据表test中新增一个字段version并设置其值为版本为2再次并发调用接口查看当前版本都为2 3.4 悲观锁有效 采用JUC、分布式锁等进行加锁此时只有获取到锁的线程才可以对这一条数据进行操作就不会出现并发问题。 修改代码这里使用JUC下的ReentrantLock Slf4j Service public class demoServiceImpl extends ServiceImplDemoMapper, Demo implements demoService {private Lock lock new ReentrantLock();OverrideTransactional(rollbackFor Exception.class)public void test(Long id, String relId) {lock.lock();// 获取主档对象Demo demo getById(id);// 打印当前线程获取到的ids列表log.info(Thread Name:{}, before demo:{},Thread.currentThread().getName(), demo);// 获取当前关联明细idListString idsList Arrays.stream(demo.getIds().split(,)).collect(Collectors.toList());// 添加新的元素去重操作省略idsList.add(relId);// 更新关联字段demo.setIds(idsList.stream().collect(Collectors.joining(,)));// 打印当前线程获取到的ids列表log.info(Thread Name:{}, after demo:{},Thread.currentThread().getName(), demo);updateById(demo);lock.unlock();} }结果成功 3.5 其他方法 如果有其他更好的方法欢迎讨论
http://www.sczhlp.com/news/223138/

相关文章:

  • 国外流行的内容网站自动推广软件
  • 免费建站的网站哪个好企业服务账号是什么
  • 做餐饮企业网站的费用怎样找做淘宝客的网站
  • 创建网站域名多少钱桃城网站建设
  • 什么网站没人做如何做微信商城网站
  • 2025 废气处理/废气治理/环保/污水/分子筛/除臭设备推荐榜:上海深城以专利技术破局,3 家企业凭场景适配登榜,助力异味治理升级
  • Web3 行业 Solidity 高级后端开发工程师岗位要求
  • todolist
  • 来宾网站制作重庆传媒公司前十名
  • 苏州网站设计电话企业微信开放平台
  • 上海做网站比较好的公司合肥装饰公司做的好的网站
  • 从化网站建设公司做网站所需要的项
  • 2018做电影网站还能赚钱吗网站建设开发工具
  • 为企业做网站还有前途吗杨浦集团网站建设
  • 有哪些网站或者公司招募做视频的wordpress 做图库栏目
  • 新农村建设的网站中企动力初期做的网站
  • 长沙网站seo服务phpwind 做企业网站
  • 山东住房和城乡建设厅网站首页桂林wordpress招聘
  • 天津网站制作南昌wordpress很好的博客
  • wordpress企业建站流程wordpress流动公告
  • 九江做网站哪家公司好旅游网站界面设计
  • 怎么才能让自己做的网站上传到百度搜关键字可以搜到关于集团网站建设的
  • 散文网站模板枣强网站建设代理
  • 网站的建设服务中心如何创建一个简单的网站
  • 营销型网站建设答辩优秀作文网站推荐
  • 网页设计实训总结模板域名对网站seo的影响吗
  • 专门做预售的网站当前最新域名
  • 搜索引擎营销简称seo抓取的网站如何做seo
  • 阿里云能放企业网站吗学广告设计难不难
  • tornado做网站免费咨询矢量图