zoukankan      html  css  js  c++  java
  • SQLite也可能出现死锁

    提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。
    下面举个例子:
    连接1:BEGIN (UNLOCKED)
    连接1:SELECT ... (SHARED)
    连接1:INSERT ... (RESERVED)
    连接2:BEGIN (UNLOCKED)
    连接2:SELECT ... (SHARED)
    连接1:COMMIT (PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)
    连接2:INSERT ... (尝试获取RESERVED锁,但已有PENDING锁未释放,返回SQLITE_BUSY)
    现在2个连接都在等待对方释放锁,于是就死锁了。当然,实际情况并没那么糟糕,任何一方选择不继续等待,回滚事务就行了。

    不过要更好地解决这个问题,就必须更深入地了解事务了。
    实际上BEGIN语句可以有3种起始状态:
    DEFERRED:默认值,开始事务时不获取任何锁。进行第一次读操作时获取SHARED锁,进行第一次写操作时获取RESERVED锁。
    IMMEDIATE:开始事务时获取RESERVED锁。
    EXCLUSIVE:开始事务时获取EXCLUSIVE锁。

    现在考虑2个事务在开始时都使用IMMEDIATE方式:
    连接1:BEGIN IMMEDIATE (RESERVED)
    连接1:SELECT ... (RESERVED)
    连接1:INSERT ... (RESERVED)
    连接2:BEGIN IMMEDIATE (尝试获取RESERVED锁,但已有RESERVED锁未释放,因此事务开始失败,返回SQLITE_BUSY,等待用户重试)
    连接1:COMMIT (EXCLUSIVE,写入完成后释放)
    连接2:BEGIN IMMEDIATE (RESERVED)
    连接2:SELECT ... (RESERVED)
    连接2:INSERT ... (RESERVED)
    连接2:COMMIT (EXCLUSIVE,写入完成后释放)
    这样死锁就被避免了。

    而EXCLUSIVE方式则更为严苛,即使其他连接以DEFERRED方式开启事务也不会死锁:
    连接1:BEGIN EXCLUSIVE (EXCLUSIVE)
    连接1:SELECT ... (EXCLUSIVE)
    连接1:INSERT ... (EXCLUSIVE)
    连接2:BEGIN (UNLOCKED)
    连接2:SELECT ... (尝试获取SHARED锁,但已有EXCLUSIVE锁未释放,返回SQLITE_BUSY,等待用户重试)
    连接1:COMMIT (EXCLUSIVE,写入完成后释放)
    连接2:SELECT ... (SHARED)
    连接2:INSERT ... (RESERVED)
    连接2:COMMIT (EXCLUSIVE,写入完成后释放)
    不过在并发很高的情况下,直接获取EXCLUSIVE锁的难度比较大;而且为了避免EXCLUSIVE状态长期阻塞其他请求,最好的方式还是让所有写事务都以IMMEDIATE方式开始。
    顺带一提,要实现重试的话,可以使用sqlite3_busy_timeout()或sqlite3_busy_handler()函数。

    由此可见,要想保证线程安全的话,可以有这4种方式:

    • SQLite使用单线程模式,用一个专门的线程访问数据库。
    • SQLite使用单线程模式,用一个线程队列来访问数据库,队列一次只允许一个线程执行,队列里的线程共用一个数据库连接。
    • SQLite使用多线程模式,每个线程创建自己的数据库连接。
    • SQLite使用串行模式,所有线程共用全局的数据库连接。


    作者:Crazy2015
    链接:https://www.jianshu.com/p/15051fbd5a35
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    python深度学习之灾难求生预测(titanic)
    python深度学习之语音识别(speech recognize)
    greenplum集群状态恢复与同步
    python手写图片识别MNIST
    python随机森林房价预测
    机器学习常用模型
    python爬虫优化和错误日志分析
    数据挖掘数学基础
    虚拟机spark集群搭建
    虚拟机zookeeper和hbase集群搭建
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10684926.html
Copyright © 2011-2022 走看看