使用NHibernate时如何避免ID冲突,但数据库表也在外部更新?

Lou*_*hys 1 .net oracle nhibernate sequence

我正在使用NHibernate,使用XML映射.数据库是ORACLE.客户实体有这样的东西

<class name="CustomerEntity" table="CUSTOMER">
    <id name="Id" column="ID" type="int">
      <generator class="sequence">
        <param name="sequence">CUSTOMER_ID</param>
      </generator>
    </id>
    ... (something)
 </class>
Run Code Online (Sandbox Code Playgroud)

并且其他对象ID被类似地映射.但是,有时用户也会更新数据库,比如插入新客户,我担心他们添加的ID可能会与序列生成的数字冲突,从而导致异常并且无法添加新客户.

目前我通过使序列以非常高的值(例如10,000)开始来欺骗它,因此序列生成的数字不太可能与用户输入的数字相同(当然它们会输入类似1,2的东西) ,100等).然而,这仍然存在风险且不干净.

如何解决这个问题呢?我应该在所有代码中加上try-catch-repeat吗?请注意,如果已经使用了下一个数字,这仍然会导致诸如非常长的循环之类的问题.

sle*_*ske 5

如果用户直接更新数据库,他们确实也应该使用序列.那是,

INSERT (id, a, b, ...) VALUES (seq.nextval, 'bla', 'blo', ) INTO SOMETABLE
Run Code Online (Sandbox Code Playgroud)

如果他们不这样做,你真的无法避免碰撞.

可以通过读取所有ID(SELECT MAX(ID) FROM SOMETABLE)检查"已占用"ID ,然后将序列更改为从上面开始,但当然只有在某些用户输入另一个记录之后才能使用.

您可以在每次操作之前执行"免费ID"检查,但这可能会非常慢.

我只能看到两个真正的解决方案:

  • 确保所有插入使用序列生成ID.也许写一个存储过程供用户使用,或者一些帮助程序......
  • 使用UUID作为ID,而不是整数.这当然需要更改架构.

而顺便说一句:为什么您的用户需要直接访问数据库?这让我觉得非常不寻常(而且很危险,原因很多,其中一个是你描述的).通过提供一些前端或至少一些存储过程,考虑以某种方式控制/调解访问.否则用户教育似乎是你唯一的选择......