美文网首页
Sqlite事务锁状态以及死锁问题

Sqlite事务锁状态以及死锁问题

作者: 突击手平头哥 | 来源:发表于2019-10-20 21:20 被阅读0次

    Sqlite事务锁

    Sqlite事务中锁的状态

    • 1 UNLOCKED: 表示数据库并未开启任何读写, 使用BEGIN开启一个事务时就是该状态
    • 2 SHARED: Sqlite可以同时多线程读取, 再进行SELECT操作就会获得该锁, 同时可以被多线程事务持有
    • 3 RESERVED: 表示数据库准备写入数据库, 同一时间只能被一个持有, 但是并不禁止持有SHARED
    • 4 PENDING: 在真正写入之前等待其他SHARED的释放
    • 5 EXCLUSIV: 表示可以写入数据库了, 其他线程不再能对数据库进行任何读写操作了

    一个事务

    BEGIN(UNLOCKED)
    SELECT...(SHARED)
    INSERT...(RESERVED)
    COMMIT(PENDING)
    

      一个事务大致会经过如上流程进行一个修改数据库操作, 但是我们可以看到: 在COMMIT时需要等待其他线程释放SHARED锁, 那么假设另外一个事务进行了读取操作下一步等待进行插入操作, 那么就进入了死锁

    //线程1               //线程2
    BEGIN(UNLOCKED)     
                        BEGIN(UNLOCKED)
    SELECT...(SHARED)
                        SELECT...(SHARED)
    INSERT...(RESERVED) 
    COMMIT(PENDING)...
                        INSERT...
    

      COMMITINSERT各自等待对方的锁释放, 造成了死锁

    BEGIN起始状态

    • 1 BEGIN 不获取任何锁
    • 2 BEGIN IMMEDIATE: 开启时获取RESERVED锁,
    • 3 BEGING EXCLUSIVE: 开启时获取EXCLUSIV

      RESERVED同时不允许多个获取, 所以不允许同时开启两个IMMEDIATE方式的事务; EXCLUSIVE方式来说, 即使使用BEGIN开启了另外一个事务, 也无法进行任何查看更改操作了

    如果把SQlite数据库用于特别复杂或要求很高的场景, 其多线程的安全使用还是很需要考量的!

    总结

    • 1 如果要求不高的情况下可以使用序列化的方式, 全局使用同一个连接
    • 2 如果对多线程有要求的话, 建议使用一个单线程独立访问数据库
    • 3 Sqlite所谓的线程安全保障的时数据库的安全, 而并不保证语句的正确执行; 实际工作中往往需要的时即使短时间阻塞或者延时但是语句能够执行下去

    相关文章

      网友评论

          本文标题:Sqlite事务锁状态以及死锁问题

          本文链接:https://www.haomeiwen.com/subject/xdnamctx.html