sqlalchemy lock and atomic
prepare:
Prepare a table
set evn
DBUSER=root
DBPASS=
DBNAME=cyborg
TBNAME="atomic"
RDNAME="s0"
DB create
DBNAME=atomic
mysql -u$DBUSER -p$DBPASS <<< "create DATABASE $DBNAME"
Delete DB
mysql -u$DBUSER -p$DBPASS <<< "drop database $DBNAME"
table create
mysql -u$DBUSER -p$DBPASS $DBNAME <<< "CREATE TABLE $TBNAME(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
PRIMARY KEY (id))ENGINE=InnoDB DEFAULT CHARSET=utf8;
desc $TBNAME"
Delete table
mysql -u$DBUSER -p$DBPASS $DBNAME <<< "DROP TABLE $TBNAME"
insert table
mysql -u$DBUSER -p$DBPASS $DBNAME <<< "INSERT INTO $TBNAME
(name)
VALUES
(\"s0\");"
update table
TBNAME="atomic"
RDNAME="s0"
mysql -u$DBUSER -p$DBPASS $DBNAME <<<"UPDATE $TBNAME SET name='$RDNAME' WHERE id=1"
数据库锁(DB lock)
sqlalchemy 使用with_lockmode锁住DB锁(不是sqlalchemy 实现的锁)
test.py 如下:
from sqlalchemy import create_engine,Table,Column,Integer,String,MetaData,ForeignKey
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
import time
import sys
print(sys.argv)
mode = sys.argv[1] if len(sys.argv) > 1 else "get"
print("DB for %s" % mode) Base = declarative_base()
Session = sessionmaker() engine = create_engine("mysql://root:123@localhost/cyborg")
Session.configure(bind=engine)
session = Session() class Atomic(Base):
__tablename__ = 'atomic'
id = Column(Integer, primary_key=True)
name = Column(String) def __str__(self):
return 'Atomic[%d, %s]' % (self.id, self.name) at_id = 1
filer_name = "s0"
exp_name = "s1"
wait = 10
print("start to get lock", time.strftime("%H:%M:%S"))
if mode == "get":
lock = session.query(Atomic).with_for_update().filter(
Atomic.id == at_id).first()
# remove with_for_update, "update" mode no need wait to get lock
print("get lock: ", time.strftime("%H:%M:%S"))
print(lock)
print("lock the record and wait for %s", wait)
time.sleep(wait)
session.commit()
else:
lock = session.query(Atomic).filter_by(name=filer_name).with_for_update().update(
{"name": exp_name}, synchronize_session="fetch")
print(lock)
print("get lock: ", time.strftime("%H:%M:%S"))
print("update the record and wait for %s", wait)
time.sleep(wait)
session.commit()
print(lock)
先执行update,再read
在terminal 1执行:
python2 test.py update
在terminal 2执行:
python2 test.py
很明显读取需要等待时间。
或者
mysql -u$DBUSER -p$DBPASS $DBNAME <<< "select * from $TBNAME"
不需要等待时间。
先执行read ’python2 test.py’,再update也需要等待。
New in version 0.9.0: Query.with_for_update() supersedes the Query.with_lockmode() method.
结论:
update的时候,即使不指定with_for_update, 也会自动获取这个update锁。
仅仅query的时候,如果不指定with_for_update, 那么立即执行,不会获取这个锁。
sqlalchemy session 执行 delete 时 synchronize_session 策略 (update 同样适用)
False: 不同步 session,如果被删除的 objects 已经在 session 中存在,在 session commit 或者 expire_all 之前,这些被删除的对象都存在 session 中。
不同步可能会导致获取被删除 objects 时出错。
fetch: 删除之前从 db 中匹配被删除的对象并保存在 session 中,然后再从 session 中删除,这样做是为了让 session 的对象管理 identity_map 得知被删除的对象究竟是哪些以便更新引用关系。
evaluate: 默认值。根据当前的 query criteria 扫描 session 中的 objects,如果不能正确执行则抛出错误,这句话也可以理解为,如果 session 中原本就没有这些被删除的 objects,扫描当然不会发生匹配,相当于匹配未正确执行。
from sqlalchemy import create_engine,Table,Column,Integer,String,MetaData,ForeignKey
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()
Session = sessionmaker() engine = create_engine("mysql://root:123@localhost/cyborg")
Session.configure(bind=engine)
session = Session() class Atomic(Base):
__tablename__ = 'atomic'
id = Column(Integer, primary_key=True)
name = Column(String) q = session.query(Atomic)
a = q.filter_by(name="s1")
print(type(a))
print(a)
at = a.one()
print(a.one())
import ipdb; ipdb.set_trace()
# "fetch" "evaluate"
a1 =a.update({"name": "s2"}, synchronize_session=False)
print(type(a1))
print(a1)
print(Atomic.name=="s1")
session.commit()
print(a.one())
REF:
SQL Atomic Operation on UPDATE and DELETE
SQLAlchemy ORM Examples (推荐,一个系列,一共11个部分)
Cyborg DB example:
mysql:
DBUSER=root
DBPASS=y0devstk
DBNAME=cyborg
TBNAME="attach_handles"
RDNAME=0
FIELD="in_use"
QR_NAME="deployable_id" QR_VALUE=`mysql -u$DBUSER -p$DBPASS $DBNAME <<<"SELECT $QR_NAME FROM $TBNAME LIMIT 1" | tail -n 1`
mysql -u$DBUSER -p$DBPASS $DBNAME <<<"UPDATE $TBNAME SET $FIELD=$RDNAME WHERE $QR_NAME=$QR_VALUE"
mysql -u$DBUSER -p$DBPASS $DBNAME <<<"SELECT $FIELD FROM $TBNAME WHERE $QR_NAME=$QR_VALUE"
python
import cyborg.conf
import cyborg.db.sqlalchemy.models
from oslo_db import options
from cyborg import context
from cyborg import db as db_api
user="root"
psw="y0devstk"
# connection_debug=1,
# connection_trace=True,
# set_override
CONF = cyborg.conf.CONF
CONF(["--config-file=/etc/cyborg/cyborg.conf"])
options.set_defaults(CONF)
# options.set_defaults(CONF,
# connection="mysql+pymysql://%s:%s@127.0.0.1/cyborg?charset=utf8" % (user, psw))
print(CONF["database"].items())
# from oslo_context import context
ct = context.get_admin_context()
sqlalchemy_api = db_api.get_instance()
try:
r = sqlalchemy_api.attach_handle_list(ct)
r0 = r[0]
print(r0.in_use)
# r = sqlalchemy_api.attach_handle_allocate(ct, r0.attach_type, r0.deployable_id)
r1 = sqlalchemy_api.attach_handle_allocate(ct, r0.deployable_id)
print(r1.in_use)
except Exception as e:
print(e)
openstack oslo.config
sqlalchemy lock and atomic的更多相关文章
- ReetrantLock Synchronized Atomic的性能对比
之前看到了一篇帖子关于Lock和Synchronized的性能,写的是Lock比Synchronized的性能要好,可是,我试了下,结果却不是这样的,我所使用的JDK的版本是1.7,可能跟原帖作者用的 ...
- java中的Atomic类
文章目录 问题背景 Lock 使用Atomic java中的Atomic类 问题背景 在多线程环境中,我们最常遇到的问题就是变量的值进行同步.因为变量需要在多线程中进行共享,所以我们必须需要采用一定的 ...
- 工作队列(workqueue) create_workqueue/schedule_work/queue_work
--- 项目需要,在驱动模块里用内核计时器timer_list实现了一个状态机.郁闷的是,运行时总报错"Scheduling while atomic",网上搜了一下:" ...
- go sync.Mutex 设计思想与演化过程 (一)
go语言在云计算时代将会如日中天,还抱着.NET不放的人将会被淘汰.学习go语言和.NET完全不一样,它有非常简单的runtime 和 类库.最好的办法就是将整个源代码读一遍,这是我见过最简洁的系统类 ...
- [内核]Linux workqueue
转自:http://blog.chinaunix.net/uid-24148050-id-296982.html 一.workqueue简介workqueue与tasklet类似,都是允许内核代码请求 ...
- JAVA并发的性能调整
1.互斥技术 synchronized Lock Atomic 性能比较Atomic > Lock > synchronized,当然这不是绝对的.当线程数比较少时,synchroni ...
- Java并发控制机制详解
在一般性开发中,笔者经常看到很多同学在对待java并发开发模型中只会使用一些基础的方法.比如Volatile,synchronized.像Lock和atomic这类高级并发包很多人并不经常使用.我想大 ...
- obj-c编程10:Foundation库中类的使用(6)[线程和操作队列]
任何语言都不能避而不谈线程这个东东,虽然他是和平台相关的鸟,虽说unix哲学比较讨厌线程的说...线程不是万能灵药,但有些场合还是需要的.谈到线程就不得不考虑同步和死锁问题,见如下代码: #impor ...
- Java编程思想 - 并发
前言 Q: 为什么学习并发? A: 到目前为止,你学到的都是有关顺序编程的知识,即程序中的所有事物在任意时刻都只能执行一个步骤. A: 编程问题中相当大的一部分都可以通过使用顺序编程来解决,然而,对于 ...
随机推荐
- 2.NET Core设定数据库种子
1.使用以下代码在 Models 文件夹中创建一个名为 SeedData 的新类: using Microsoft.EntityFrameworkCore;using Microsoft.Extens ...
- SpringBoot开发验证码功能
简介 验证码主要是用来防止恶意破解密码.刷票.论坛灌水.刷页.Kaptcha 是一个可高度配置的实用验证码生成工具,使用也很简单,这里就使用它来做验证码. 另外使用JAVA原生的API也可以实现验证码 ...
- JUC - Monitor监控ThreadPoolExecutor
JUC - Monitor监控ThreadPoolExecutor 一个自定义Monitor监控ThreadPoolExecutor的执行情况 TASK WokerTask class WorkerT ...
- nodeJS从入门到进阶一(基础部分)
一.Node.js基础知识 1.概念 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是JavaScript的运行环境 Node.js 使用了一个事件驱动.非阻塞 ...
- DataPipeline如何实现数据质量管理?
数据质量管理已经成为数据治理的重要组成部分.高质量的数据是企业进行决策的重要依据. DataPipeline数据质量平台整合了数据质量分析.质量校验.质量监控等多方面特性, 以保证数据质量的完整性.一 ...
- IDEA 阿里巴巴代码规范检查插件
1.问题概要 大家都想写出规范的代码,可规范的标准是什么勒,估计每个人心中的标准都不是完全一致的 在分工合作越来越精细化的时代,我们需要一个最大程度接近公认的规范,这里我们以阿里巴巴的代码规范作为参考 ...
- 【OGG】OGG的单向复制配置-支持DDL(二)
[OGG]OGG的单向复制配置-支持DDL(二) 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的 ...
- mysql 设置查看字符集
MySQL查看和修改字符集的方法 一.查看字符集 1.查看MYSQL数据库服务器和数据库字符集 方法一:show variables like '%character%';方法二:show var ...
- Centos7安装DockerCE
1. 说明 以下使用的系统为centos7,64位,镜像为CentOS-7-x86_64-Minimal-1804,所有操作以root用户操作 2. 安装Docker官方源 2.1 安装yum工具集 ...
- Linux chown命令详解使用格式和方法
指令名称 : chown 使用权限 : root(一般来说,这个指令只有是由系统管理者(root)所使用,一般使用者没有权限可以改变别人的文件拥有者,也没有权限可以自己的文件拥有者改设为别人.只有系统 ...