关于两个update语句互相死锁的显现,加深我们对锁的了解
初步了解更新锁(U)与排它锁(X)
有类似这样的表及数据12345678910111213CREATE TABLE dbo.tb( c1 int, c2 char(10), c3 varchar(10));GODECLARE @id int;SET @id = 0;WHILE @id <5BEGIN; SET @id = @id + 1; INSERT dbo.tb VALUES( @id, 'b' + RIGHT(10000 + @id, 4), 'c' + RIGHT(100000 + @id, 4) );END;
在查询一中执行更新操作12345BEGIN TRANUPDATE dbo.tb SET c2 = 'xx' WHERE c1 = 2;WAITFOR DELAY '00:00:30';UPDATE dbo.tb SET c2 = 'xx' WHERE c1 = 5;ROLLBACK;
在查询一执行开始后,马上在查询二中执行 ...
死锁的四个必要条件
必要条件
互斥条件
资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。
不可剥夺条件
进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。
请求和保持条件
进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
循环等待条件
在发生死锁时必然存在一个进程等待队列{P1,P2,…,Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所深情地资源。以上给出了导致死锁的四个必要条件,只要系统发生死锁则以上四个条件至少有一个成立。事实上循环等待的成立蕴含了前三个条件的成立,似乎没有必要列出然而考虑这些条件对死锁的预防是有利的,因为可以通过破坏四个条件中的任何一个来预防死锁的发生。
死锁预防我们可以通过破坏死锁产生的4个必要条件来 预防死锁,由于资源互斥是资源使用的固有特性是 ...
mysql记录锁(record lock),间隙锁(gap lock),Next-key锁(Next-key lock)
记录锁(record lock)这是一个索引记录锁,它是建立在索引记录上的锁(主键和唯一索引都算),很多时候,锁定一条数据,由于无索引,往往会导致整个表被锁住,建立合适的索引可以防止扫描整个表。如:开两个会话,两个事务,并且都不commit,该表有主键,两个会话修改同一条数据,第一个会话update执行后,第二个会话的update是无法执行成功的,会进入等待状态,但是如果update别的数据行就可以成功。再例如:开两个会话,两个事务,并且都不commit,并且该表无主键无索引,那么第二个会话不管改什么都会进入等待状态。因为无索引的话,整个表的数据都被第一个会话锁定了。
间隙锁(gap lock)MySQL默认事务隔离级别是可重复读,这个隔离级别为了避免幻读现象,引入了这个间隙锁,对索引项之间的间隙上锁。
Next-key锁(Next-key lock)Next-key锁实际上是Record锁和gap锁的组合。Next-key锁是在下一个索引记录本身和索引之前的gap加上S锁或是X锁(如果是读就加上S锁,如果是写就加X锁)。默认情况下,InnoDB的事务隔离级别为RR,系统参数innod ...
SqlAlchemy 标记字段变更
在数据库里面存储一些结构化数据12345678910111213141516171819202122232425class JSON(TypeDecorator): """ Json String Field """ impl = Text def process_bind_param(self, value, dialect): if value is None: return value elif isinstance(value, (dict, list)): return json.dumps(value) else: raise ValueError("unsupported value type") def process_result_value(self, value, dialect): if value is None: ...
SQLAlchemy会话与事务控制:互斥锁和共享锁
for updateSQLAlchemy 的 Query 支持 select … for update / share
12session.Query(User).with_for_update().first()session.Query(User).with_for_update(read=True).first()
完整形式
1with_for_update(read=False, nowait=False, of=None)
read
是标识加互斥锁还是共享锁. 当为 True 时, 即 for share 的语句, 是共享锁. 多个事务可以获取共享锁, 互斥锁只能一个事务获取.有”多个地方”都希望是”这段时间我获取的数据不能被修改, 我也不会改”, 那么只能使用共享锁.
nowait
其它事务碰到锁, 是否不等待直接”报错”.
of
指明上锁的表, 如果不指明, 则查询中涉及的所有表(行)都会加锁.
扩展with_for_update实际对应mysql的 SELECT ... FOR UPDATE 语句, 但是在使用时要注意, 由于InnoDB 预设是 ...
BasicColumn 自定义行内容
BasicColumn 配置1234567const columns: BasicColumn[] = [ { title: 'yourTitle', dataIndex: 'yourDataIndex', slots: {customRender: 'yourSlotName'}, },];
页面使用12345<BasicTable @register="register"> <template #yourSlotName="{ record }"> {{ record['yourDataIndex'] }} </template></BasicTable>
python 检测编码 & 正确解码 bytes
12345678def test(): import chardet data = b"\xe4\xb8\xad\xe6\x96\x87" if isinstance(data, bytes): encoding = chardet.detect(data)["encoding"] print("encoding", encoding) text = data.decode(encoding, "ignore") print("text", text)
web监听窗口滚动事件,并判断是否滚动到底部
1234567891011121314const handleScroll = () => { let scrollTop = document.documentElement.scrollTop || document.body.scrollTop; let clientHeight = document.documentElement.clientHeight; let scrollHeight = document.documentElement.scrollHeight; if (scrollTop + clientHeight >= scrollHeight) { console.log("滚动到底部了") }}onMounted(() => { window.addEventListener('scroll', handleScroll)})onUnmounted(() => { win ...
python给图片加上背景
1234567891011121314def add_background_to_the_image(): from PIL import Image # 加载原始图片 image = Image.open('img.png') # 创建背景 background = Image.new('RGB', (2000, 2000), (255, 255, 255)) # 将原始图片放置在背景上 background.paste(image, (100, 100)) # 保存结果图片 background.save('img_res.png')
eslint 配置文件
安装1npm install --save-dev eslint
.eslintignore1234567891011121314*.shnode_modules*.md*.woff*.ttf.vscode.ideadist/public/docs.husky.local/binDockerfile
.eslintrc.js1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980// @ts-checkconst {defineConfig} = require('eslint-define-config');module.exports = defineConfig({ root: true, env: { browser: true, n ...