1

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

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

4

3 回答 3

1

在spring框架中有类似的东西

@Transactional(rollbackFor=RuntimeException.class)

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

于 2012-05-08T08:37:00.387 回答
0

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

于 2012-05-08T08:49:09.040 回答
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;

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

于 2012-05-08T09:22:45.013 回答