MYSQL自动递增主键的实际问题

时间:2012-05-08 08:29:29

标签: java mysql persistence auto-increment

我最近为我的java应用程序编写了一个会计模块。

该模块基于MYSQL表和INNODB Engine。 其中一个要求当然是每张发票的“运行”ID。 我尝试使用auto_increment方法和使用序列表生成id,但在两者中我都有同样的问题:因为当我持久保存发票实体时生成id,如果在刷新期间发生错误持久化实体到数据库,auto_id递增,在我的系列发票中造成“漏洞”。 我当然可以放弃这种方法,并为新发票分配以前发票的最大ID + 1,但我认为这是一种不好的做法。我可以使用哪些其他方法来确保我的发票系列中没有漏洞,假设由于某些验证问题导致发票偶尔无法保存。

3 个答案:

答案 0 :(得分:1)

在spring框架中有类似

的东西
@Transactional(rollbackFor=RuntimeException.class)

所以如果服务器调用出现问题,应该回滚一切。我确信其他框架也有类似的方法。

答案 1 :(得分:0)

如果你的MySQL版本> 5.0.2然后你可以尝试使用触发器,它会正确地增加表列的值。 但你应该记得,委托给数据库的发票编号的生成,这与业务逻辑更相关,我认为,这不是一个好主意,因为在失败的情况下你可能会遇到一些问题。所以我建议你在代码中以编程方式生成它。

答案 2 :(得分:0)

这本身并不差,但可能值得拥有一个不同的“传统”数字主键字段来保证表格的结构完整性,并为发票号码设置另一个字段。

然后,您可以使用不同的逻辑填充该发票编号,或者只是简单的 MAX + 1 ,或者可以通过从密钥表中查找,以允许不同类型的发票的不同编号序列。

例如:

CREATE TABLE `keys` (
    `id` INT NOT NULL auto_increment,
    `type` VARCHAR(10) NOT NULL,
    `prefix` VARCHAR(10) NOT NULL,
    `value` INT(10) NOT NULL DEFAULT 0,
    PRIMARY KEY (`id`)
);

INSERT INTO `keys` (`type`, `prefix`) VALUES
('Sales Receipt', 'SRI'),
('Sales Invoice', 'SIN'),
('Sales Refund', 'SRF');

然后在你的(伪)代码中你可以做

Database.BeginTransaction;
NewInvNum = Database.Query("SELECT `value` FROM `keys` WHERE `type` = 'SIN'");
MyInvoice.InvoiceNumber = NewInvNum;
Database.SaveInvoice(MyInvoice);
Database.Query("UPDATE `keys` SET `value` = {0} WHERE `type` = 'SIN'", NewInvNum+1);
Database.CommitTransaction;

事务(或其他一些并发保护)很重要,因此当正在创建多个发票时,它们不会得到相同的数字。

相关问题