mysql 的两条数据同时保存成功问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kayseen
V2EX    Python

mysql 的两条数据同时保存成功问题

  •  
  •   kayseen 2019-11-29 09:43:23 +08:00 5533 次点击
    这是一个创建于 2212 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如现在有两张表,分别是class表和studend表,

    现在两张表都是空的,并且在student表里面有一个字段是class_id,

    两张表需要同时新建一条数据: class1student1,

    并且student1class_id字段需要指向class1的 id,

    请问这种场景应该怎么实现才能让他们保持一致性,并且student1class_id可以指向class1的 id?

    因为class1没有保存的时候,是没有 id 字段的,

    还是说这种场景下不能保持一致性啊

    31 条回复    2019-11-29 18:20:54 +08:00
    kayseen
        1
    kayseen  
    OP
       2019-11-29 09:44:36 +08:00
    简单描述的话, 就是两条数据需要同时保存成功,但是在一条数据里需要记录另外一条数据的 id......
    ysoserious
        2
    ysoserious  
       2019-11-29 09:45:58 +08:00
    事务
    joyme
        3
    joyme  
       2019-11-29 09:46:44 +08:00
    事务不能解决这个问题吗
    Reficul
        4
    Reficul  
       2019-11-29 09:50:06 +08:00 via Android
    事物,非要强一致可以加外键。不一致不会死人就程序逻辑保证
    U7Q5tLAex2FI0o0g
        5
    U7Q5tLAex2FI0o0g  
       2019-11-29 09:58:35 +08:00
    你说的同时是有多同时啊
    0.000000000000001 秒的同时吗
    先插入 class1,得到 class1 的 id,再插入 student1,放到事务执行,也可以说是同时啊
    hmxxmh
        6
    hmxxmh  
       2019-11-29 09:59:39 +08:00
    事务加外键吧,django 可以用 with transaction.atomic()进入事务
    markgor
        7
    markgor  
       2019-11-29 10:07:06 +08:00   2
    代,如果也偷,你技的道路也走到了。
    如果你是,那思路你。
    事物。
    插入 class 表,取 insertid。
    插入 studend 表
    任何一部出,都 rollback,
    成功都 commit。
    kayseen
        8
    kayseen  
    OP
       2019-11-29 10:10:08 +08:00
    @markgor
    谢谢你帮忙解答,是新手,但是从头到尾我说要代码了吗?还有技术的道路走到尽头???
    rockyou12
        9
    rockyou12  
       2019-11-29 10:11:29 +08:00
    @kayseen 应为你这个问题太过低级……任何看过一点数据库文档的人都不会问你这个问题……
    kayseen
        10
    kayseen  
    OP
       2019-11-29 10:11:45 +08:00
    @ysoserious
    @joyme
    @Reficul
    @littleylv
    @hmxxmh
    谢谢大家解答,现在知道了,本来知道可以事务操作,不知道事务之后会有数据的 id,感谢
    kayseen
        11
    kayseen  
    OP
       2019-11-29 10:12:20 +08:00
    @rockyou12
    好的,大神
    justRua
        12
    justRua  
       2019-11-29 10:12:48 +08:00
    class1 没有保存的时候,是没有 id 字段的。你可以用某些规则生成 id,这样两条插入语句就可以并行执行。例如:用 crc32 计算 className 的值,再在插入的时候指定 classId 就好了
    kayseen
        13
    kayseen  
    OP
       2019-11-29 10:14:22 +08:00
    @justRua
    嗯呢,谢谢啦, 我本来也是纠结不保存没有 id 的问题,上面各位介绍了事务之后就有 id 了,可以看下
    dongisking
        14
    dongisking  
       2019-11-29 10:37:22 +08:00
    不建议增加外键,7#的方法可取
    DonaidTrump
        15
    DonaidTrump  
       2019-11-29 10:39:05 +08:00 via iPhone
    事务都有 flush 和 commit 两种动作,flush 的时候就有 id 了,这个时候还可以 rollback,commit 之后就不能 rollback 了
    blodside
        16
    blodside  
       2019-11-29 10:40:37 +08:00
    先整个数据库的课看看吧。不用直接看文档,比到处问来的效率高。
    事务的基础知识包括:CAID、4 种隔离级别之类的。
    justRua
        17
    justRua  
       2019-11-29 10:40:41 +08:00
    mysql 通过 SELECT LAST_INSERT_ID()可以拿取到,你这不就是获取自增 id 的问题么。还以为你要多线程并发插入
    MatthewHan
        18
    MatthewHan  
       2019-11-29 10:42:16 +08:00
    ACID 数据库本身就是可以保证原子性的,假设在代码中是 2 个步骤对持久层的处理,把这个两步当做一个整体,要么全部执行,要么全部不执行。
    augustpluscn
        19
    augustpluscn  
       2019-11-29 10:59:36 +08:00
    事务,class 保存后不用等 commit 就能获取到 id 了
    markgor
        20
    markgor  
       2019-11-29 11:01:48 +08:00
    @kayseen

    比如现在有两张表,分别是 class 表和 studend 表,
    :有表

    现在两张表都是空的,并且在 student 表里面有一个字段是 class_id
    :面一字段叫 class_id

    两张表需要同时新建一条数据: class1 和 student1,
    :法理解同插入 class1 和 studen1 ,竟上面提字段,唯一字段是 class_id,行自行各插入

    并且 student1 的 class_id 字段需要指向 class1 的 id,
    :student1.class_id class1.id;(上面表名是 class 和 studend 就了,也自行算了。)

    请问这种场景应该怎么实现才能让他们保持一致性,并且 student1 的 class_id 可以指向 class1 的 id?
    :如何保持 student1.class_id class1.id 的。

    因为 class1 没有保存的时候,是没有 id 字段的,
    :那如果先保存 class1 致什後果?

    还是说这种场景下不能保持一致性啊
    :你了?自己出的才是真。


    另外,
    不是事务之后会有数据的 id,
    你只要 ID 是使用 AI 的,插入後都能取自增 ID。
    事物的是了保第二句插入的候有意外能把第一步的操作取消了(回)。


    最後,我言可能有些偏激。
    我意思是如果你非新手的,你技道路基本是走到了。
    geying
        21
    geying  
       2019-11-29 11:05:05 +08:00
    @markgor 老哥真走心 顶你
    VictorJing94
        22
    VictorJing94  
       2019-11-29 11:49:59 +08:00   2
    ....这个应用不对吧...什么情况下会需要同时创建 class 和 student 呢...楼主不妨再好好思索一下
    Joyboo
        23
    Joyboo  
       2019-11-29 12:02:24 +08:00
    还是用事务吧,外键一堆坑
    julyclyde
        24
    julyclyde  
       2019-11-29 14:21:56 +08:00
    @VictorJing94 显然你是对的,且仅你是对的
    reus
        25
    reus  
       2019-11-29 15:11:02 +08:00
    事务都不知道,建议返厂重修。
    ukipoi
        26
    ukipoi  
       2019-11-29 15:12:39 +08:00
    @VictorJing94
    学生必须在一个班里才被记录成本校学生。
    学校不限制招生。
    一个班级满了,会新开一个班来安排学生。
    这种情况算么?
    luofan004
        27
    luofan004  
       2019-11-29 15:28:32 +08:00
    你们再这样子,吓得楼主都不敢问问题了。
    waterlaw
        28
    waterlaw  
       2019-11-29 15:51:18 +08:00 via Android
    mysql 的事务是通过锁保证的,acid 严格来说不一定对,可以看下数据库的共享锁,写锁,排他锁,以及快照读(一个事务获得写锁修改另一个事务可以读该记录最近的快照), 一致性就事务加回滚,spring 的话就 @Transactional(propagation=Propagation.REQUIRED, rockbsck=Exception.class), 用 mysql 默认可重复读隔离级别就可以了
    akira
        29
    akira  
       2019-11-29 16:58:13 +08:00
    就这个场景而言。。并不需要那么严谨。。
    VictorJing94
        30
    VictorJing94  
       2019-11-29 17:20:32 +08:00
    @ukipoi 不算吧,反正多操作就是事务,场景举例不对就是了,我也就吐槽一下不严谨的举例
    markgor
        31
    markgor  
       2019-11-29 18:20:54 +08:00
    @ukipoi 有牛角尖了吧...
    第一步,必是查班有,了就去另一班。返回班 ID。
    第二步,把第一步返回的班 ID 校的表。

    你的件是:
    生必定班才算本校生。
    班了新班,但不限量。

    所以根件,流程自然是先查班人是否再做。
    第二步是把第一步的班 ID 校,
    最後得出的果就是生是 XXX 班 XXX 校的生。

    A.ID B.AID 就定了是必先有 A 才有 B。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2662 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 11:46 PVG 19:46 LAX 03:46 JFK 06:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86