zoukankan      html  css  js  c++  java
  • loopback 05

    数据并发处理

    ACID性质

    • 原子性(Atomicity): 要么全部被执行,要么都不执行;
    • 一致性(Consistency): 满足完整性约束;
    • 隔离性(Isolation): 不应影响其他事务的执行;
    • 持久性(Durability : 永久保存在数据库中;

    隔离级别

    • 未提交读(Read uncommitted): 允许脏读,可以看到其他事务尚未提交的修改;
    • 提交读(Read committed): 写锁一直保持到事务结束,读锁在SELECT操作完成后马上释放,不要求范围锁;
    • 可重复读(Repeatable reads) : 读锁和写锁一直保持到事务结束,不要求范围锁;
    • 可序列化(Serializable): 读锁和写锁保持直到事务结束后才能释放,查询中使用“WHERE”子句来获得一个范围锁;
    • 较高的隔离级别能更好地保证数据一致性,但反过来会影响程序的并发性能;

    读现象

    • 脏读: 当一个事务允许读取另外一个事务修改但未提交的数据;
    • 不可重复读: 一行数据获取两遍得到不同的结果(发生在SELECT 操作没有获得读锁或者SELECT执行完后马上释放了读锁)
    • 幻读: 两个完全相同的查询语句执行得到不同的结果集(没有获取范围锁的情况下执行SELECT ... WHERE操作可能会发生);

    隔离级别vs读现象

    隔离级别 脏读 不可重复读 幻读
    未提交读 可能发生 可能发生 可能发生
    提交读 可能发生 可能发生
    可重复读 可能发生
    可序列化

    隔离级别vs 锁持续时间

    • s: 锁持续到当前语句执行完毕
    • c: 锁会持续到事务提交
    隔离级别 写操作 读操作 范围操作
    未提交读 s s s
    提交读 c s s
    可重复读 c c s
    可序列化 c c c

    数据库默认隔离级别

    • MySQL: Repeatable read;
    • PG : Read committed;

    loopback事务分离处理

    一个例子

    let currnetTx = null;
    
    return Vote.count({
          userId,
          title: 'voteA:最美coser',
          created_at: {
            between: [`2015-12-${now.getDate()}`, `2015-12-${now.getDate() + 1}`]
          }
        }).then(count=> {
          if(count > 0) {
            return res.send({code:2, msg: 'voted before'});
          }
    
          return Vote.beginTransaction({
            isolateionLevel: Vote.Transaction.REPEATABLE_READ,
            tiemout: 30000
          }).then(tx=> {
            currentTx = tx
            if(userId === staticId) return;
            return Vote.create({userId, itemId: instanceId, title: 'voteA:最美coser'}, {transaction: currentTx});
          }).then(()=>{
            return VoteA.findOne({where: {itemId: instanceId}}, {transaction: currentTx})
          }).then(voteA=> {
            return voteA.updateAttributes({count: ++voteA.count}, {transaction: currentTx})
          }).then(()=> {
            if(currentTx) currentTx.commit();
            console.log(`最美coser: userId-${userId} vote itemId-${instanceId}`);
            return res.send({code: 1, msg: 'success!'});
          })
        }).catch(err=> {
          if(currentTx) currentTx.rollback();
          console.log(err);
          return res.status(500).end();
        })
    
    

    loopback类型

    • loopback中获取的时间类型就为Date对象;
    • loopback中使用查询涉及到时间时使用UTC时间;

    loopback一个插入数据脚本例子

    //seedDate
    
    export const figureCategories = {
      pvc: {name: '静态PVC'},
      GK: {name: 'GK'},
      figma: {name: 'figma'},
      pf: {name: 'PF'},
      human: {name: '人形'}
    }
    
    export const brandData = {
      pvc: [
        {name: 'Bandai/万代'},
        {name: 'Goodsmile'},
        {name: 'MegaHouse'}
      ],
      GK: [
        {name: 'Bandai/万代'},
        {name: 'Goodsmile'},
        {name: 'MegaHouse'}
      ],
      figma: [
        {name: 'Bandai/万代'},
        {name: 'Goodsmile'},
        {name: 'MegaHouse'}
      ],
      pf: [
        {name: 'Bandai/万代'},
        {name: 'Goodsmile'},
        {name: 'MegaHouse'}
      ],
      human: [
        {name: 'Bandai/万代'},
        {name: 'Goodsmile'},
        {name: 'MegaHouse'}
      ]
    }
    
    //seed
    
    import Promise from 'bluebird';
    import {figureCategories, brandData} from './seedData-01.js';
    
    export default function(app, done) {
      const FigureCategory = app.models.figureCategory;
      const FigureBrand = app.models.figureBrand;
    
      function initSeedData(category, brands) {
        return FigureCategory.findOrCreate({
          where: {name: category.name}
        }, category).then(category=>{
          return Promise.resolve(brands).map(brand=>{
            return FigureBrand.findOrCreate({
              where: {name: brand.name}
            }, brand).then(brand=>{
              return category[0].brands.add(brand[0]).catch(console.log);
            })
          }, {concurrency: 1});
        }).catch(console.log);
      }
    
      Promise.resolve(Object.keys(figureCategories)).map(key=>{
        return initSeedData(figureCategories[key], brandData[key])
      }, {concurrency: 1}).then(()=>{
        done();
      }).catch(done);
    }
    
    

    数据库层面的匹配

    • scope设置在json文件
    {
      "scope": {
        "limit": 10,
        "where": {
          "status": "online"
        }
      }
    }
    
  • 相关阅读:
    dos命令大全
    死亡之ping(Ping of Death)
    硬盘安装系统
    DataGrid实现逻辑分页
    DropDownList另一种写法
    DataGrid3
    DataGrid2
    hidden(隐藏域)
    sql合并列
    未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出
  • 原文地址:https://www.cnblogs.com/jinkspeng/p/5000328.html
Copyright © 2011-2022 走看看