您的位置:首页 > 运维架构

loopback 05

2015-11-27 12:47 337 查看

数据并发处理

数据库事务

事务隔离

ACID性质

原子性(Atomicity): 要么全部被执行,要么都不执行;

一致性(Consistency): 满足完整性约束;

隔离性(Isolation): 不应影响其他事务的执行;

持久性(Durability : 永久保存在数据库中;

隔离级别

未提交读(Read uncommitted): 允许脏读,可以看到其他事务尚未提交的修改;

提交读(Read committed): 写锁一直保持到事务结束,读锁在
SELECT
操作完成后马上释放,不要求范围锁;

可重复读(Repeatable reads) : 读锁和写锁一直保持到事务结束,不要求范围锁;

可序列化(Serializable): 读锁和写锁保持直到事务结束后才能释放,查询中使用“WHERE”子句来获得一个范围锁;

较高的隔离级别能更好地保证数据一致性,但反过来会影响程序的并发性能;

读现象

脏读: 当一个事务允许读取另外一个事务修改但未提交的数据;

不可重复读: 一行数据获取两遍得到不同的结果(发生在
SELECT
操作没有获得读锁或者
SELECT
执行完后马上释放了读锁)

幻读: 两个完全相同的查询语句执行得到不同的结果集(没有获取范围锁的情况下执行
SELECT ... WHERE
操作可能会发生);

隔离级别vs读现象

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

隔离级别vs 锁持续时间

s
: 锁持续到当前语句执行完毕

c
: 锁会持续到事务提交

隔离级别写操作读操作范围操作
未提交读sss
提交读css
可重复读ccs
可序列化ccc

数据库默认隔离级别

MySQL: Repeatable read;

PG : Read committed;

官文

例子

loopback事务分离处理

transaction

一个例子

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"
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: