V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
WhyAreYouSoSad
V2EX  ›  程序员

SQL 多个事务并发提交,导致出现脏数据写入??

  •  
  •   WhyAreYouSoSad · 2017-11-13 09:43:48 +08:00 · 3668 次点击
    这是一个创建于 2563 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是这样的,同一时间内出现多个 Request 进来,同时提交了多组数据进数据库。操作的是同一个表。导致有一些不符合规则的被写进数据库。具体操作如下

    begin tran Tran1

    insert into table A //因为并发,导致程序里生产的主键重复,所以 A 没插入成功

    insert into table B //是 A 的子表

    if(@@error==0)

    begin
    COMMIT TRAN Tran1 return 0;

    end

    else
    begin
    ROLLBACK TRAN Tran1
    return -1; end

    大致就是上面这个操作。后面产生的结果是,别的事务的脏数据(B 表的那些,A 主键重复)插入到事务成功的 Insert 数据里。如何做才能避免这种错误

    7 条回复    2017-11-13 15:10:39 +08:00
    infoflow
        1
    infoflow  
       2017-11-13 09:48:28 +08:00
    A 没插成功就不要继续插入 B 了,马上回滚事务。
    xmh51
        2
    xmh51  
       2017-11-13 10:18:30 +08:00
    导致程序里生产的主键重复 这段能再详细点吗? 建议主键不要在程序生成的,用数据库里面的主键生成。
    nullcc
        3
    nullcc  
       2017-11-13 10:26:31 +08:00
    可能是数据库的事务隔离级别的问题,你可以尝试把提交读(RC)改为可重复读(RR)试试。
    fuyufjh
        4
    fuyufjh  
       2017-11-13 10:33:22 +08:00
    1 楼正解
    Hozzz
        5
    Hozzz  
       2017-11-13 11:23:15 +08:00
    锁机制的问题,执行 DML 操作的时候难道不是锁行或锁表吗?
    WhyAreYouSoSad
        6
    WhyAreYouSoSad  
    OP
       2017-11-13 11:52:45 +08:00
    @nullcc #3 为什么要改成可重复读?
    klgd
        7
    klgd  
       2017-11-13 15:10:39 +08:00
    if(@@error==0) 判断谁的 error ?不管是 insert A 还是 B,结果都应该在判断条件里的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1843 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 16:38 · PVG 00:38 · LAX 08:38 · JFK 11:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.