Giter VIP home page Giter VIP logo

knowledge's People

Contributors

tzdy avatar

Stargazers

 avatar

Watchers

 avatar

knowledge's Issues

pg查看以及修改隔离级别

文章

PostgreSQL支持的隔离级别:

  • serializable
  • repeatable read (mysql默认)
  • read committed
  • read uncommitted
    PostgreSQL默认的隔离级别为read committed。

查看当前默认的隔离级别:
show default_transaction_isolation;
查看当前的隔离级别:
show transaction_isolation;

  1. 修改PostgreSQL默认的隔离级别
    修改配置文件postgresql.conf,设置默认的隔离级别,如下:

vim postgresql.conf
default_transaction_isolation = 'read committed'

重新加载配置:
pg_ctl -D /data/pg reload

  1. 动态修改PostgreSQL隔离级别
    修改隔离级别必须在事务中执行,可以修改默认的隔离级别和当前会话的隔离级别,语法如下:

set default_transaction_isolation='repeatable read';
set transaction isolation level serializable;
select pg_reload_conf();

nodejs使用oracledb连接oracle

本地开发

windows 下载一个oracle client后,

// process.env.ORACLE_LIB_DIR 就是oracle client的文件夹路径
oracledb.initOracleClient({ libDir: process.env.ORACLE_LIB_DIR });

docker alpine 预装oracle client

FROM alpine:latest
# Install Instantclient Basic Light Oracle and Dependencies
RUN apk --no-cache add libaio libnsl libc6-compat curl && \
    cd /tmp && \
    curl -o instantclient-basiclite.zip https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip -SL && \
    unzip instantclient-basiclite.zip && \
    mv instantclient*/ /usr/lib/instantclient && \
    rm instantclient-basiclite.zip && \
    ln -s /usr/lib/instantclient/libclntsh.so.19.1 /usr/lib/libclntsh.so && \
    ln -s /usr/lib/instantclient/libocci.so.19.1 /usr/lib/libocci.so && \
    ln -s /usr/lib/instantclient/libociicus.so /usr/lib/libociicus.so && \
    ln -s /usr/lib/instantclient/libnnz19.so /usr/lib/libnnz19.so && \
    ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1 && \
    ln -s /lib/libc.so.6 /usr/lib/libresolv.so.2 && \
    ln -s /lib64/ld-linux-x86-64.so.2 /usr/lib/ld-linux-x86-64.so.2

ENV ORACLE_BASE /usr/lib/instantclient
ENV LD_LIBRARY_PATH /usr/lib/instantclient
ENV TNS_ADMIN /usr/lib/instantclient
ENV ORACLE_HOME /usr/lib/instantclient

手动建docker镜像

  1. 先拉一个ubuntu镜像,将pm2, nodejs,+08:00时区拷贝进去。
  2. 去隔壁mysql容器中,将/usr/lib/ x86_64-linux-gnu拷贝到新镜像的对应位置。
  3. 下载一个https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.htmloracle client
  4. 将cracle client拷贝进容器中。把.so后面的版本号去掉。
  5. 将oracle client中的libnnz11.so 链接到/usr/lib中(可能是libnnz19.so,根据下载的版本变化 )
  6. commit 一个新镜像

使用nodejs的mysql2时,经常中断。

mysql的wait_timeout全局变量表示操作超时时间,当连接超过一定时间没有活动后,会自动关闭该连接,这个值默认为28800(即8小时)。

  1. 使用线程池
  2. 捕获mysql连接异常err.code === 'PROTOCOL_CONNECTION_LOST'然后重新连接。

使用nodejs做文件上传/下载时,中文名需要特殊处理,否则会乱码

上传时使用formData

router.post('/upload', (req, res) => {
    const file = req.files.file[0]
    // 转成utf-8
    Buffer.from(file.originalname, 'latin1').toString('utf-8')
})

下载时使用Content-Disposition相应头时,需要注意filename是否为中文。

// 统一encodeURIComponent()更安全。
'Content-Disposition': 'attachment; filename=' + encodeURIComponent(fileName)

同时运行的进程数是有限制的。

可以通过ulimit -u查看最大运行数。

nodejs在用child_process调用其他二进制文件时(eg.. git, wc),会受到最大进程的影响,如果达到最大进程数,就会报错.

Error: read ENOTCONN
    at tryReadStart (node:net:614:20)
    at Socket._read (node:net:625:5)
    at Socket.Readable.read (node:internal/streams/readable:487:10)
    at Socket.read (node:net:666:39)
    at new Socket (node:net:415:12)
    at Object.Socket (node:net:286:41)
    at createSocket (node:internal/child_process:328:14)
    at ChildProcess.spawn (node:internal/child_process:445:23)
    at spawn (node:child_process:700:9)
    at /Users/mac/Documents/web/server/gogs/ty-git/dist/git.js:59:46
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -57,
  code: 'ENOTCONN',
  syscall: 'read'
}

删除cookie

  1. 如果设置了httpOnly,就需要用Set-Cookie清除。
  2. 没有设置httpOnly,可以直接在前端用js清除
connect.sid=; Max-Age=0; Path=/; Expires=Thu, 30 Mar 2023 01:32:47 GMT

max-age设置0 or -1. 或者expires设置过去的时间。 (优先使用max-age)

mysql多对多添加对应关系,删除对应关系。

例如user, role, user_role三张表。当需要增加对应关系时,user_role对应关系表中的user_id, role_id有唯一索引,如果两个人同时加,就会报错。

可以使用INSERT IGNORE INTO的方法,就不会报错了

Set-Cookie设置path

  1. ajax http请求携带cookie匹配path时,是根据实际ajax http请求地址来判断。
  2. 不同路径可以互相设置cookie。
  3. 子路径可以访问父路径的cookie。兄弟path之间不能访问 /sub可以访问 /的。。。/sub不能访问/sub1的

目前,express-session不能给其它路径设置cookie,也没必要

如果有编辑操作,需要预处理一下,尽可能把数字变成字符串处理。

由于大部分input组件都会把用户输入的数据转化为字符串
所以模版中的判断最好也用字符串 <div v-if="op === '1'"></div>

编辑的时候一般是哪一个字段修改才发送哪一个字段,编辑前存一个备份,点击发送的时候,对比两份数据。
如果不做预处理的话,有些字段后端返回的可能是数字,或者数字表示boolean,,input组件输入后会把这些类型都变成字符串。就没法对比了。

// 初始化字段
function initEditForm(form) {
      if (form) {
        form = { ...form }
        Object.keys(form).forEach(k => {
          // 数字转字符串
          if (typeof form[k] === 'number') {
            form[k] = form[k] + ''
          }
         // null, undefined 转空字符串
          if (typeof form[k] === 'undefined' || form[k] === null) {
            form[k] = ''
          }
        })
        form.alwaysShow = !!form.alwaysShow
        form.hidden = !!form.hidden
        return form
      }
      return {
        id: '',
        parentId: '',
        type: 1,
        label: '',
        path: '',
        index: 0,
        redirect: '',
        alwaysShow: false,
        hidden: false,

        uniqueCode: '',
        componentPath: ''
      }
    }

vue中父组件与其slot作用域中组件scss的加载顺序。

场景:需要引入一个类似bootstrap的scss库,但是不希望污染全局。

<template>
    <div>
        <slot></slot>
    </div>
</template>

<script lang="ts">
export default defineComponent({

})
</script>

<style lang="scss" scoped>
:deep() {
    & {
        // Global requirements
        @import "@primer/css/support/index.scss";
        @import '@primer/css/core/index.scss';
        @import '@primer/css/subhead/index.scss';
        @import '@primer/css/alerts/index.scss';
        @import '@primer/css/avatars/index.scss';
        @import '@primer/css/dropdown/index.scss';
        @import '@primer/css/header/index.scss';
        @import '@primer/css/labels/index.scss';
        @import '@primer/css/loaders/index.scss';
        @import '@primer/css/popover/index.scss';
        @import '@primer/css/timeline/index.scss';
        @import '@primer/css/toasts/index.scss';
        @import '@primer/css/toggle-switch/index.scss';
        @import '@primer/css/select-menu/index.scss';
        @import '@primer/css/marketing/index.scss';
        @import '@primer/css/breadcrumb/index.scss';
        @import '@primer/css/progress/index.scss';
        @import '@primer/css/markdown/index.scss';
    }
}
</style>

然后所有需要使用scss的组件放在Container组件的slot中。

<template>
  <Container>
    <div class="mx-2 px-2"></div>
  </Container>
</template>

但是这样会有一个问题。

css的加载顺序为 先slot中组件的css 再 Container中的css。这就导致了,相同css权重的情况下,slot中组件的css会被Container中的覆盖。

所以如果想在slot中组件自定义css,就要注意加!important

使用nodejs docker容器

使用ubuntu,还是alpine

如果是写一个常规的nodejs后端服务(CRUD)可以选择alpine,优点是比较小看着舒服。
如果需要调用很多花里胡哨的东西,使用alpine就可能不兼容。

# alpine
docker pull node:lts-alpine3.17
# ubuntu
docker pull node

注意事项

时区问题

容器中的时区可能是+00:00时区,在连接数据库的时候,可以在连接配置中配置+08:00时区。但是如果调用别人的服务,需要传送时间字符串(不是时间戳)的时候。

// 一个常规的格式化时间的方法
function padStart(val: number, num: number) {
  return (val + "").padStart(num, "0");
}

export function format(dateStr: string | number) {
  const date = new Date(dateStr);
  return `${date.getFullYear()}-${padStart(date.getMonth() + 1, 2)}-${padStart(
    date.getDate(),
    2
  )}`;
}

nodejs默认会根据本地时区显示时间,如果容器中是+00:00时区,那么format(Date.now())就会是8小时以前。

sequelize findOne include时,不能正确设置attributes

将subQuery设置为false,就可以正常在查询顶部设置attributes

当使用了limit时,subQuery会默认为true,就不能在最上层的attributes中统一设置别名之类的,而且不能用*

 const user = (await User.findOne({       
            attributes: ['*', [sequelize.col('org.org_code'), 'orgCode']],     
            include: {
                as: 'org',
                through: {
                    attributes: []
                },
                model: Org,
            },
             subQuery: false,
            raw: true,
        }))

pg行级锁

参考

在 Postgres 9.3 和 9.4 中有四种类型的行级锁:

更新(FOR UPDATE) - 这种模式导致 SELECT 读取的行的更新被锁定。这可以防止它们被其他事务锁定,修改或删除。即尝试 UPDATE、DELETE、SELECT FOR UPDATE、SELECT FOR NO KEY UPDATE、SELECT FOR SHARE 或 SELECT FOR KEY SHARE 的其他事务将被阻塞。删除一行,更新一些列也可以获得到此种锁模式(目前的列集是指那些具有唯一索引,并且可被用作外键 - 但将来这可能会改变)。

无键更新(FOR NO KEY UPDATE) - 这种模式与 FOR UPDATE 相似,但是更弱 - 它不会阻塞SELECT FOR KEY SHARE 锁模式。它通过不获取更新锁的 UPDATE 命令获得。

共享(FOR SHARE) - 这种模式与无键更新锁类似,除了它可以获取共享锁(非排他)。一个共享锁阻止其他事务在这些行上进行 UPDATE,DELETE,SELECT FOR UPDATE 或 SELECT FOR NO KEY UPDATE 操作,但并不阻止它们进行 SELECT FOR SHARE 或 SELECT FOR KEY SHARE。

键共享(FOR KEY SHARE)- 行为类似于共享,但该锁是较弱的:阻止了 SELECT FOR UPDATE,但不阻止 SELECT FOR NO KEY UPDATE。一个键共享锁阻止其他事务进行 DELETE 或任何更改该键值的 UPDATE,但不妨碍任何其他 UPDATE、SELECT FOR NO KEY UPDATE、SELECT FOR SHARE 或者SELECT FOR KEY SHARE。

行级锁冲突:
屏幕快照 2023-05-13 下午7 32 21

vue-router push中的replace: true的使用场景

比点击进入github一个仓库,然后进入这个页面后,ajax向后端发送请求,相应的结果是这个仓库不存在,接下来需要跳转到404页面。

在这个场景中,由于已经进入页面了,才跳转。所以当前页面历史栈为:
点击前页面A--点击后跳转的页面B--404页面C。

这时候如果跳转404页面replace: false,那么点击一次返回,只能返回到B页面。

如果replace: true的话,点击一次返回就会回到A页面。

mysql建表指定排序规则

CREATE TABLE user(
    id INTEGER AUTO_INCREMENT,
    username VARCHAR(32) NOT NULL COLLATE utf8mb4_bin,
    nickname VARCHAR(32) NOT NULL,
    password VARCHAR(32) NOT NULL COLLATE utf8mb4_bin,
    avatar_type INTEGER DEFAULT 0,
    avatar_version INTEGER DEFAULT 0,
    PRIMARY KEY ( `id` )sql_server
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci

username, password区分大小写

jwt expires

jwt过期可以通过两种方式设置。

  • iat表示签发时间戳(一定会有) 单位 s
  • exp表示超时时间戳 单位 s

一,在签发token的时候设置过期时间

import jwt from 'jsonwebtoken'
jwt.sign(
        {
            payload,
        },
        process.env.JWT_SECRET,
        { expiresIn: '1h' }
    )
// { payload: { id: 1 }, iat: 1678841275, exp: 1678844875 }

二,在解析token的时候设置过期时间

jwt.verify(token, process.env.JWT_SECRET, {
        maxAge: '1h',
})

如果同时使用两种方式,只要有一个到期,就算token过期。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.