数据库并发设计 并发 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 trans(transid,transno...)考虑直接使用transid auto_increment “这样会造成同时很多台机器插入数据时transid会重复” 这个场景是不是可以理解成:应用端有N台机器,进行并发操作,往一台db服务器里面写数据?另外transid会重复,把transid字段设置成自增长的,就可以了,另外你数据库的隔离级别是什么类型的?疑惑:为什么你的trans扩展表非要做联合主键啊,我觉得没有必要,去掉联合主键,只把表的自增业务id作为主键就OK了。 应用端有N台机器,进行并发操作,往一台db服务器里面写数据? 是这样的。你的意思是trans表的TransID自增,然后 TransDetail和其他2个表加一个ID来实现自增,取消联合主键吗? 应用端有N台机器,进行并发操作,往一台db服务器里面写数据? 是这样的。你的意思是trans表的TransID自增,然后 TransDetail和其他2个表加一个ID来实现自增,取消联合主键吗?是的啊,我看你表设计里面,每个表都有自增主键了。比如:transdetail(transid,itemid,...) 里面的itemid不是自增的吗?transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗? 自增的话其他表如何如何实现自增? 因为插入的话是4个表同时插入数据?这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。 应用端有N台机器,进行并发操作,往一台db服务器里面写数据? 是这样的。你的意思是trans表的TransID自增,然后 TransDetail和其他2个表加一个ID来实现自增,取消联合主键吗?是的啊,我看你表设计里面,每个表都有自增主键了。比如:transdetail(transid,itemid,...) 里面的itemid不是自增的吗?transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗?里面的ID都不是自增的,都是自己添加的。例如:Trans(200,000001),TransDetail 是(200,1,...)(200,2,...)(200,3,...)TransCondiment(200,2,1),(200,2,2),transpayment(100,200),transpayment(10q,200) paymentID是一直加下去的,不过数据库设定paymentID也不是自增的,而是手动+1的。所以就造成并发问题. 自增的话其他表如何如何实现自增? 因为插入的话是4个表同时插入数据?这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。Trans表可以自增,但是其他几个表都要获取到TransID才可以插入数据。比如2台机器同时插入,这样的话last_insert_id会不会一样? 当前的插入数据是这样的:1张单据存储在Trans中,单据中所有的产品存在TransDetail中,产品的不同属性存在TransCondiment中,单据的付款信息存在TransPayment中.所以Trans中的TransID是连接所有表信息的主键。 应用端有N台机器,进行并发操作,往一台db服务器里面写数据? 是这样的。你的意思是trans表的TransID自增,然后 TransDetail和其他2个表加一个ID来实现自增,取消联合主键吗?是的啊,我看你表设计里面,每个表都有自增主键了。比如:transdetail(transid,itemid,...) 里面的itemid不是自增的吗?transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗?里面的ID都不是自增的,都是自己添加的。例如:Trans(200,000001),TransDetail 是(200,1,...)(200,2,...)(200,3,...)TransCondiment(200,2,1),(200,2,2),transpayment(100,200),transpayment(10q,200) paymentID是一直加下去的,不过数据库设定paymentID也不是自增的,而是手动+1的。所以就造成并发问题.我觉得你这不是叫做并发的问题啊,一个db里面有事务,有锁啊,你select到的都是最新的记录条数。你insert的时候,如果看到已经有了,会报主键重复的错误啊,不可能让你插入重复值的。多台机器插入数据时transid会重复,你这个重复到底是哪个表的哪些字段数据会重复呢?如果可以你把这些字段设置成唯一键试试看。 自增的话其他表如何如何实现自增? 因为插入的话是4个表同时插入数据?这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。Trans表可以自增,但是其他几个表都要获取到TransID才可以插入数据。比如2台机器同时插入,这样的话last_insert_id会不会一样?不会一样的。 你insert的时候,如果看到已经有了,会报主键重复的错误啊,不可能让你插入重复值的。当然事务提交的时候会看到主键重复错误,所以现在是不要出现这种插入错误,可以同时插入不报错的. 加上事务,Begin Trans,insert 第一张表,得到last_insert_id然后依次插入后边几张表commit trans有异常,则rollback这是事务处理的最典型应用啊,怎么会有重复?难道你用错了引擎类型? 楼主我告诉你使用for update 可以解决你的问题。 额。你想当然了。我估计情况是这样的。A事务开启 获取transid = 1;计算出新的transid 为 2,注意此事A事务没提交B事务开启 获取transid = 1(因为A还没提交),计算新的transid = 2这样就重复了。 楼主你的情况我猜测是这样的。A事务开启 获取transid = 1;计算出新的transid 为 2,注意此事A事务没提交B事务开启 获取transid = 1(因为A还没提交),计算新的transid = 2解决方案是这样的: 查询transid的时候使用for update, select transid from tab_name where ..... for update这样就可以解决重复的问题了。不过如果你并发非常高的话效率可能会有影响,因为使用了for update,下个事务执行这里的时候会等到这个事务commit之后才会执行。实际上不是并发处理了。 MySQL存储过程中,如何在MySQL的控制台打印消息? Navicat 8 for mysql 创建存储过程 这条子查询如何改成联合查询? 关于MySql数据库数据类型(在线求答) mysql存储过程 送分了。 在线等!!! asp网站mssql 换成mysql!!! 高分求助mysql字符集修改问题,请高手指教! 如何判断表是否存在? memslap如何获取压力测试结果? 关于mysql启动失败的问题 话题与回复 MySQL 5.6 安装卡住了,求助~!
比如:
transdetail(transid,itemid,...) 里面的itemid不是自增的吗?
transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?
transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗?
这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。
比如:
transdetail(transid,itemid,...) 里面的itemid不是自增的吗?
transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?
transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗?
里面的ID都不是自增的,都是自己添加的。
例如:Trans(200,000001),TransDetail 是(200,1,...)(200,2,...)(200,3,...)
TransCondiment(200,2,1),(200,2,2),
transpayment(100,200),transpayment(10q,200) paymentID是一直加下去的,不过数据库设定paymentID也不是自增的,而是手动+1的。
所以就造成并发问题.
这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。
Trans表可以自增,但是其他几个表都要获取到TransID才可以插入数据。
比如2台机器同时插入,这样的话last_insert_id会不会一样?
1张单据存储在Trans中,单据中所有的产品存在TransDetail中,产品的不同属性存在TransCondiment中,单据的付款信息存在TransPayment中.所以Trans中的TransID是连接所有表信息的主键。
比如:
transdetail(transid,itemid,...) 里面的itemid不是自增的吗?
transcondiment(transid,itemid,condimentid,...)的condimentid呢,不是自增的吗?
transpayment(transid,paymentid,....)的paymentid呢,不是自增的吗?
里面的ID都不是自增的,都是自己添加的。
例如:Trans(200,000001),TransDetail 是(200,1,...)(200,2,...)(200,3,...)
TransCondiment(200,2,1),(200,2,2),
transpayment(100,200),transpayment(10q,200) paymentID是一直加下去的,不过数据库设定paymentID也不是自增的,而是手动+1的。
所以就造成并发问题.
我觉得你这不是叫做并发的问题啊,一个db里面有事务,有锁啊,你select到的都是最新的记录条数。
你insert的时候,如果看到已经有了,会报主键重复的错误啊,不可能让你插入重复值的。多台机器插入数据时transid会重复,你这个重复到底是哪个表的哪些字段数据会重复呢?如果可以你把这些字段设置成唯一键试试看。
这样的所有进程不需要考虑锁trans表,直接插入,然后last_insert_id 得到transid,再向其它表插入数据即可。
Trans表可以自增,但是其他几个表都要获取到TransID才可以插入数据。
比如2台机器同时插入,这样的话last_insert_id会不会一样?
不会一样的。
Begin Trans,
insert 第一张表,得到last_insert_id
然后依次插入后边几张表
commit trans
有异常,则rollback
这是事务处理的最典型应用啊,怎么会有重复?
难道你用错了引擎类型?
额。你想当然了。我估计情况是这样的。
A事务开启 获取transid = 1;计算出新的transid 为 2,注意此事A事务没提交
B事务开启 获取transid = 1(因为A还没提交),计算新的transid = 2这样就重复了。
A事务开启 获取transid = 1;计算出新的transid 为 2,注意此事A事务没提交
B事务开启 获取transid = 1(因为A还没提交),计算新的transid = 2解决方案是这样的:
查询transid的时候使用for update,
select transid from tab_name where ..... for update
这样就可以解决重复的问题了。不过如果你并发非常高的话效率可能会有影响,因为使用了for update,下个事务执行这里的时候会等到这个事务commit之后才会执行。实际上不是并发处理了。