C# 复杂主键中Max(ID)的替代项
我正在制作一个发票系统,支持多个子公司,每个子公司都有自己的发票号码集,因此我有一个主键为(Subsidiary,InvoiceNo)的表 我不能使用MySQL自动递增字段,因为它将不断递增所有子数据的相同计数 我不想为每个子公司制作单独的表格,因为需要时会添加新的子公司 我目前正在使用表中的“选择最大(ID),其中子公司=X”,并根据此添加发票 我使用的是nHibernate,发票插入在InvoiceItem插入之前,因此如果发票插入失败,InvoiceItem将不会执行。但是我将捕获异常,重新检索Max(ID)并重试 这种方法有什么问题?如果有的话,还有什么替代方案C# 复杂主键中Max(ID)的替代项,c#,database,nhibernate,primary-key,C#,Database,Nhibernate,Primary Key,我正在制作一个发票系统,支持多个子公司,每个子公司都有自己的发票号码集,因此我有一个主键为(Subsidiary,InvoiceNo)的表 我不能使用MySQL自动递增字段,因为它将不断递增所有子数据的相同计数 我不想为每个子公司制作单独的表格,因为需要时会添加新的子公司 我目前正在使用表中的“选择最大(ID),其中子公司=X”,并根据此添加发票 我使用的是nHibernate,发票插入在InvoiceItem插入之前,因此如果发票插入失败,InvoiceItem将不会执行。但是我将捕获异常,重
问这个问题的原因是因为我读了关于这个问题的一个答案:正如您所说,这种方法的问题是多个会话可能会尝试插入相同的发票ID。您会遇到唯一的约束冲突,必须重试,也可能会失败,等等 我通过在创建新发票期间锁定子系统来解决此类问题。但是,不要锁定表,(a)如果使用InnoDB,默认情况下,
lock table
命令会出现问题。(b) 没有理由不同时添加两个不同子公司的发票,因为它们具有不同的独立发票号
在你的情况下,我会做的是:
- 打开事务并确保您的表是InnoDB
- 使用
命令。这可以在NHibernate中完成SELECT..锁定子系统。。用于更新
- 使用max(..)函数查找max id并进行插入
- 提交事务
这将序列化一个子公司的所有发票插入(即,一次只能有一个会话执行此类插入,任何第二次尝试都将等待第一次完成或回滚),但这正是您想要的。您不希望发票号码出现漏洞(例如,如果您插入发票id 3485,然后它失败,则有发票3484和3486,但没有发票3485)。正如您所说,这种方法的问题是多个会话可能会尝试插入同一发票id。您遇到唯一的约束冲突,必须重试,也可能失败,等等 我通过在创建新发票期间锁定子系统来解决此类问题。但是,不要锁定表,(a)如果使用InnoDB,默认情况下,
lock table
命令会出现问题。(b) 没有理由不同时添加两个不同子公司的发票,因为它们具有不同的独立发票号
在你的情况下,我会做的是:
- 打开事务并确保您的表是InnoDB
- 使用
命令。这可以在NHibernate中完成SELECT..锁定子系统。。用于更新
- 使用max(..)函数查找max id并进行插入
- 提交事务
这将序列化一个子公司的所有发票插入(即,一次只能有一个会话执行此类插入,任何第二次尝试都将等待第一次完成或回滚),但这正是您想要的。您不希望在发票号码中出现漏洞(例如,如果您插入发票id 3485,然后失败,则有发票3484和3486,但没有发票3485)。在生成主键时使用此方法是非常糟糕的。我的建议如下:
- 不要赋予主键商业意义(合成键)
- 使用辅助机制生成发票编号
- 附属公司李>
- 下一个语音号码
http://nhforge.org/blogs/nhibernate/archive/2009/02/09/nh2-1-0-new-generators.aspx在生成主键时使用此选项是一个非常糟糕的主意。我的建议如下:
- 不要赋予主键商业意义(合成键)
- 使用辅助机制生成发票编号
- 附属公司李>
- 下一个语音号码
http://nhforge.org/blogs/nhibernate/archive/2009/02/09/nh2-1-0-new-generators.aspx这看起来正是我要找的东西,你能再清理一下锁定过程吗。我是否需要从发票中选择*进行更新,其中subsidiary=x,然后在同一会话上进行另一个查询以获取最大id?您需要一个表
subsiduary
,其中每个subsiduary有一行。这将是您要锁定的那一行,以显示子公司正在进行独占操作<代码>启动事务,然后从子系统中选择id,其中子系统\u id=?对于UPDATE
,然后从invoice…,INSERT…
,COMMIT
,中选择MAX(id)。这样,当您锁定附属表中的附属行时,就不允许插入任何将该行作为外键约束的新记录了吗?对吗?不完全正确;如果你锁上