Codeigniter Postgresql:使用外键死锁的事务

时间:2014-06-22 19:55:32

标签: php sql codeigniter postgresql

我遇到postgresql事务的问题(使用codeigniter),这里涉及的表是:

CREATE TABLE factura(
nro_factura serial NOT NULL,
fecha_emision date NOT NULL,    
(... more columns)
PRIMARY KEY (nro_factura));

CREATE TABLE detalle(
id_articulo integer NOT NULL REFERENCES articulos(id) ON UPDATE CASCADE ON DELETE RESTRICT,
nro_factura integer NOT NULL REFERENCES factura(nro_factura) ON UPDATE CASCADE ON DELETE RESTRICT,
(... more columns)
PRIMARY KEY(id_articulo,nro_factura));

这是交易:

$this->db->trans_start();

        $queryFactura = $this->db->query("INSERT INTO factura (... all columns) VALUES (CURRENT_DATE,?,?,?,?,?,?,?,?,?,?,?,?)",$factura);

        $id_factura = $this->db->query("SELECT nro_factura FROM factura WHERE id_vehiculo=?",array($factura['id_vehiculo'])); 

        foreach ($articulos as $key){
            $queryFactura = $this->db->query("INSERT INTO detalle (id_articulo,nro_factura,precio_venta,descuento,cantidad) VALUES (?,$id_factura,?,?,?)",$key);
        } 

        $this->db->trans_complete();

现在,我无法执行SELECT查询,因为尚未进行上一个插入。如何在没有第一次插入的外键的情况下进行第二次插入?

编辑:2014年6月24日

最后我使用了postgre的currval()函数。仅替换此选择查询:

 $id_factura = $this->db->query("SELECT currval(pg_get_serial_sequence('factura', 'nro_factura'))",array())->result()[0]->currval;

1 个答案:

答案 0 :(得分:1)

如果您只需要" nro_factura"的价值从INSERT语句中,您不应该使用SELECT语句来获取它。

PostgreSQL通过其currval() function公开特定序列返回的最后一个数字。它的记录行为是

  

返回此序列的nextval最近获得的值   在本届会议上。 (如果nextval永远不会报告错误   在这个会话中被调用了这个序列。)因为这是   返回会话本地值,它给出了可预测的答案是否   或者不是其他会话自当前会话以来已执行nextval   那样。

CodeIgniter似乎在PostgreSQL函数周围包装了自己的函数$this->db->insert_id()

AFAIK,每个广泛使用的dbms的当前版本,每个ORM,以及每个数据库抽象层都包含这样的函数。