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

销售管理系统下载seo美式

销售管理系统下载,seo美式,西安制作网站公司,贵州网站制作目录 一、前言二、MySQL解决方案(InnoDB)2.1、AUTO_INCREMENT(表自增ID)2.2、FUNCTION(不能保证并发安全)2.2.1、定义FUNCTION2.2.1.1、DELIMITER2.2.1.2、last_insert_id()2.2.1.3、DETERMINISTIC 2.2.2、…

目录

  • 一、前言
  • 二、MySQL解决方案(InnoDB)
    • 2.1、AUTO_INCREMENT(表自增ID)
    • 2.2、FUNCTION(不能保证并发安全)
      • 2.2.1、定义FUNCTION
        • 2.2.1.1、DELIMITER
        • 2.2.1.2、last_insert_id()
        • 2.2.1.3、DETERMINISTIC
      • 2.2.2、不保证并发安全
    • 2.3、FUNCTION(可保证并发安全)
      • 2.3.1、定义FUNCTION
      • 2.3.2、调用
        • 2.3.2.1、原生SQL
        • 2.3.2.2、MyBatis
    • 2.4、PROCEDURE(可保证并发安全)
      • 2.4.1、定义PROCEDURE
      • 2.4.2、调用
        • 2.4.2.1、原生SQL
        • 2.4.2.2、MyBatis

一、前言

往往有很多情况下,我们需要使用自己生成的唯一Id或保证不重复的序列号,特别是在高并发的场景下。为此,很容易想到的实现方式有以下几种:

  • 通过原子操作和锁机制使用Java代码实现,在单JVM中维护内存中的序列数,另外需要自己保证持久化到外部存储系统;
  • 或者使用能保证分布式高并发下一致性的组件Zookeeper,借助于它的分布式锁很容易实现,缺点是需要在自己的系统或服务中引入Zookeeper的组件依赖,无疑增加了系统复杂度和可维护性(换用Redis也是同理);
  • 另一种容易想到的是,可以利用MySQL的保证事务性效果的操作,所以这种方式相比于第二种方式更加轻量。

本文将针对MySQL的解决方案(InnoDB存储引擎)进行介绍。

二、MySQL解决方案(InnoDB)

2.1、AUTO_INCREMENT(表自增ID)

  • 优点:MySQL内部对AUTO_INCREMENT自增ID,可以保证并发安全。
  • 缺点:每需要一组序列,可能就需要一张表,一张表不允许同时有多个AUTO_INCREMENT自增字段,不能同时维护多组序列,且不支持自定义的自增步长。

下文将介绍多组序列的方案,首先来创建一张序列表,并初始三组序列(步长increment均为1),如下:

DROP TABLEIF EXISTS sequence;
CREATE TABLEsequence
(name VARCHAR(50) NOT NULL COMMENT '序列名称',current_value BIGINT NOT NULL COMMENT '序列当前值',increment INT NOT NULL DEFAULT 1 COMMENT '序列步长',PRIMARY KEY (name)
) ENGINE=InnoDB;INSERT INTO sequence VALUES ('seq1', 0, 1);
INSERT INTO sequence VALUES ('seq2', 0, 1);
INSERT INTO sequence VALUES ('seq3', 0, 1);

2.2、FUNCTION(不能保证并发安全)

2.2.1、定义FUNCTION

DROP FUNCTION IF EXISTS `seq`;
DELIMITER $$
CREATE FUNCTION `seq`(seq_name VARCHAR(50)) RETURNS BIGINT
DETERMINISTIC
BEGIN
UPDATE sequence SET current_value=last_insert_id(current_value + increment) WHERE name=seq_name;
RETURN last_insert_id();
END $$
DELIMITER ;

下面3小节将对此FUNCTION的定义作解释。

2.2.1.1、DELIMITER

DELIMITER主要在以下情况有用:

  1. 批量执行脚本:当你写的 SQL 脚本包含多个 SQL 语句,并且其中包括存储过程、函数、触发器等,它们的内部也包含多个语句时,使用 DELIMITER 可以避免语法冲突。
  2. 存储过程、函数等复杂对象:在创建存储过程或函数时,你可能会写很多语句,这时就需要用DELIMITER更改语句分隔符,避免 MySQL 把语句内部的;当作外部的语句结束符。
2.2.1.2、last_insert_id()
  1. LAST_INSERT_ID()(无参数):返回当前会话中最近一次 INSERT 操作时生成的自动增量 ID。
  2. LAST_INSERT_ID(<value>)(带参数):将传入的值设置为当前会话的 “最后插入 ID”,并返回该值。这不会改变数据库表的内容,仅仅是设置会话的返回 ID 值。
2.2.1.3、DETERMINISTIC

在MySQL中,DETERMINISTICNO SQLREADS SQL DATA声明通常出现在创建存储过程或函数时。他们告诉MySQL如何处理函数或过程并与**二进制日志(binlog)**记录有关,以便更高效地处理binlog里的操作日志参数。点击查看更多

  1. DETERMINISTIC:表示函数或过程是纯函数或过程,即它的输出完全由输入参数确定。自MySQL 5.0.0开始,DETERMINISTIC默认值为NOT DETERMINISTIC
  2. NO SQL:表示函数或过程没有使用MySQL内置的SQL语句,而是使用其他编程语言编写的代码。
  3. READS SQL DATA:表示函数或过程的代码包含SQL语句,并且只能读取数据而不能修改数据。

2.2.2、不保证并发安全

本方案并不能保证并发安全,原因在于,虽然UPDATE是原子操作,但不同的会话其实是可能读到同样的序列数值,则会导致不同会话之间最终返回的新序列值相同。

那么,也不能在函数定义里尝试去添加事务相关的操作,如START TRANSACTIONROLLBACKCOMMIT等,因为不被支持,否则报错:1422 - Explicit or implicit commit is not allowed in stored function or trigger.

2.3、FUNCTION(可保证并发安全)

2.3.1、定义FUNCTION

原理:select ... for update行锁,保证序列记录不会被同时修改。

DROP FUNCTION IF EXISTS `seq`;
DELIMITER $$CREATE FUNCTION `seq`(seq_name VARCHAR(50)) RETURNS BIGINT
DETERMINISTIC
BEGINDECLARE new_value BIGINT;-- 使用 FOR UPDATE 锁定该行,确保只有当前事务会修改此行SELECT current_value + increment INTO new_valueFROM sequenceWHERE name = seq_nameFOR UPDATE;-- 更新 sequence 表并返回新的序列值UPDATE sequence SET current_value = new_valueWHERE name = seq_name;RETURN new_value;
END $$DELIMITER ;

2.3.2、调用

2.3.2.1、原生SQL
select `seq`('seq1');
2.3.2.2、MyBatis
<select id="getSeqByName" parameterType="java.lang.String" resultType="long">select `seq`(#{name})
</select>

2.4、PROCEDURE(可保证并发安全)

2.4.1、定义PROCEDURE

原理:在存储过程中使用事务操作保证并发安全。

DROP PROCEDURE IF EXISTS `seq`;DELIMITER $$CREATE PROCEDURE `seq`(IN seq_name VARCHAR(50), OUT new_value BIGINT)
BEGINDECLARE cur_value BIGINT;-- 开始事务START TRANSACTION;-- 获取当前值SELECT current_value INTO cur_value FROM sequence WHERE name = seq_name FOR UPDATE;-- 更新序列值UPDATE sequence SET current_value = current_value + increment WHERE name = seq_name;-- 获取更新后的值SELECT current_value INTO new_value FROM sequence WHERE name = seq_name;-- 提交事务COMMIT;
END $$DELIMITER ;

2.4.2、调用

2.4.2.1、原生SQL
-- 定义一个变量来存储输出值
SET @output_value = 0;-- 调用存储过程,传入序列名称 'seq1',并将输出存储在 @output_value 变量中
CALL seq('seq1', @output_value);-- 查看存储过程执行后的输出
SELECT @output_value AS new_value;
2.4.2.2、MyBatis

定义mapper接口:

void getSeqByName(Map<String, Object> params);

mapper接口对应的xml:

<!-- 定义参数映射 -->
<parameterMap id="seqParamMap" type="java.util.HashMap"><parameter property="seq_name" mode="IN" jdbcType="VARCHAR"/><parameter property="new_value" mode="OUT" jdbcType="BIGINT"/>
</parameterMap><!-- 调用存储过程 -->
<select id="getSeqByName" parameterMap="seqParamMap" statementType="CALLABLE">{call seq(?, ?)}
</select>

调用存储过程,获取新序列值:

Map<String, Object> params = new HashMap<>();
params.put("seq_name", "seq1");
SpringUtil.getBean(SequenceMapper.class).getSeqByName(params);
log.info("new seq value: ", params.get("new_value"));
http://www.dtcms.com/wzjs/321848.html

相关文章:

  • 做设计用的素材下载网站网络关键词排名软件
  • 适应 分辨率 网站网站建设哪家好
  • 晋城企业网站建设价格百度招聘电话
  • 洪梅网站建设国内外十大免费crm软件推荐
  • o2o网站建设代理商百度官方下载
  • 徐州做网站多少钱seo网站关键词优化报价
  • h5做招聘网站可以吗长沙seo推广外包
  • 南通技术网站网络营销平台排名
  • l辽宁建设工程信息网专业搜索引擎seo合作
  • 佛山网站开发公司电话今日热搜榜排名
  • 做网站架构需要什么步骤北京做百度推广的公司
  • 网站做301将重定向到新域名中国最厉害的营销策划公司
  • 做公司网站图片算是商用吗市场调研与分析
  • 罗湖建设网站百度首页 百度一下
  • 茂名网站建设公司网络营销包括几个部分
  • 威海做网站为什么不建议去外包公司上班
  • 营销网站类型百度关键词优化多少钱一年
  • 网上平面设计接单平台seo网站快速整站优化技术
  • 做机械的有什么网站网络服务商在哪咨询
  • wordpress 要先装PHP吗seo网络推广外包公司
  • 经纪公司排名seo搜索引擎优化报价
  • 网页设计教学设计seo精准培训课程
  • 网站系统优化如何把网站推广出去
  • 网站建设 面试问题流氓网站
  • 有什么推广网站引擎优化是什么工作
  • jquery 网站根目录智能营销系统
  • 如何添加网站白名单网络优化工程师主要负责什么工作
  • 云盘网站如何做如何自己做推广
  • 帮别人做网站进了看守所百家联盟推广部电话多少
  • 最常用的规划网站个人网站设计模板