比如现在有两张表,分别是class
表和studend
表,
现在两张表都是空的,并且在student
表里面有一个字段是class_id
,
两张表需要同时新建一条数据: class1
和student1
,
并且student1
的class_id
字段需要指向class1
的 id,
请问这种场景应该怎么实现才能让他们保持一致性,并且student1
的class_id
可以指向class1
的 id?
因为class1
没有保存的时候,是没有 id 字段的,
还是说这种场景下不能保持一致性啊
1
kayseen OP 简单描述的话, 就是两条数据需要同时保存成功,但是在一条数据里需要记录另外一条数据的 id......
|
2
ysoserious 2019-11-29 09:45:58 +08:00
事务
|
3
joyme 2019-11-29 09:46:44 +08:00
事务不能解决这个问题吗
|
4
Reficul 2019-11-29 09:50:06 +08:00 via Android
事物,非要强一致可以加外键。不一致不会死人就程序逻辑保证
|
5
littleylv 2019-11-29 09:58:35 +08:00
你说的同时是有多同时啊
0.000000000000001 秒的同时吗 先插入 class1,得到 class1 的 id,再插入 student1,放到事务执行,也可以说是同时啊 |
6
hmxxmh 2019-11-29 09:59:39 +08:00
事务加外键吧,django 可以用 with transaction.atomic()进入事务
|
7
markgor 2019-11-29 10:07:06 +08:00 2
別來騙代碼,如果連這也偷懶,你技術的道路也走到盡頭了。
如果你是剛學,那給思路你沒問題。 開啟事物。 插入 class 表,獲取 insertid。 插入 studend 表 任何一部出錯,都 rollback, 成功都 commit。 |
10
kayseen OP |
12
justRua 2019-11-29 10:12:48 +08:00
class1 没有保存的时候,是没有 id 字段的。你可以用某些规则生成 id,这样两条插入语句就可以并行执行。例如:用 crc32 计算 className 的值,再在插入的时候指定 classId 就好了
|
13
kayseen OP @justRua
嗯呢,谢谢啦, 我本来也是纠结不保存没有 id 的问题,上面各位介绍了事务之后就有 id 了,可以看下 |
14
dongisking 2019-11-29 10:37:22 +08:00
不建议增加外键,7#的方法可取
|
15
tulongtou 2019-11-29 10:39:05 +08:00 via iPhone
事务都有 flush 和 commit 两种动作,flush 的时候就有 id 了,这个时候还可以 rollback,commit 之后就不能 rollback 了
|
16
blodside 2019-11-29 10:40:37 +08:00
先整个数据库的课看看吧。不用直接看文档,比到处问来的效率高。
事务的基础知识包括:CAID、4 种隔离级别之类的。 |
17
justRua 2019-11-29 10:40:41 +08:00
mysql 通过 SELECT LAST_INSERT_ID()可以拿取到,你这不就是获取自增 id 的问题么。还以为你要多线程并发插入
|
18
MatthewHan 2019-11-29 10:42:16 +08:00
ACID 数据库本身就是可以保证原子性的,假设在代码中是 2 个步骤对持久层的处理,把这个两步当做一个整体,要么全部执行,要么全部不执行。
|
19
augustpluscn 2019-11-29 10:59:36 +08:00
事务,class 保存后不用等 commit 就能获取到 id 了
|
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。 事物的開啟是為了保證第二句插入的時候有意外能把第一步的操作取消了(回滾)。 最後,我語言可能有些偏激。 我意思是如果你非新手問這樣的問題,你技術道路基本是走到盡頭了。 |
22
VictorJing94 2019-11-29 11:49:59 +08:00 2
....这个应用不对吧...什么情况下会需要同时创建 class 和 student 呢...楼主不妨再好好思索一下
|
23
Joyboo 2019-11-29 12:02:24 +08:00
还是用事务吧,外键一堆坑
|
24
julyclyde 2019-11-29 14:21:56 +08:00
@VictorJing94 显然你是对的,且仅你是对的
|
25
reus 2019-11-29 15:11:02 +08:00
事务都不知道,建议返厂重修。
|
26
ukipoi 2019-11-29 15:12:39 +08:00
|
27
luofan004 2019-11-29 15:28:32 +08:00
你们再这样子,吓得楼主都不敢问问题了。
|
28
waterlaw 2019-11-29 15:51:18 +08:00 via Android
mysql 的事务是通过锁保证的,acid 严格来说不一定对,可以看下数据库的共享锁,写锁,排他锁,以及快照读(一个事务获得写锁修改另一个事务可以读该记录最近的快照), 一致性就事务加回滚,spring 的话就 @Transactional(propagation=Propagation.REQUIRED, rockbsck=Exception.class), 用 mysql 默认可重复读隔离级别就可以了
|
29
akira 2019-11-29 16:58:13 +08:00
就这个场景而言。。并不需要那么严谨。。
|
30
VictorJing94 2019-11-29 17:20:32 +08:00
@ukipoi 不算吧,反正多操作就是事务,场景举例不对就是了,我也就吐槽一下不严谨的举例
|