[英]Codeigniter Postgresql: Transaction with foreign key deadlock
我在使用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;
如果只需要INSERT語句中的“ nro_factura”值,則不應使用SELECT語句來獲取它。
PostgreSQL通過currval()函數公開特定序列返回的最后一個數字。 它記錄的行為是
返回當前會話中nextval最近為該序列獲取的值。 (如果從未在此會話中為此序列調用nextval,則會報告一個錯誤。)由於此方法返回的是會話本地值,因此它提供了一個可預測的答案,即自當前會話執行以來,其他會話是否已執行nextval。
CodeIgniter似乎在該PostgreSQL函數周圍包裝了自己的函數$ this-> db-> insert_id() 。
AFAIK,每個廣泛使用的dbms,每個ORM和每個數據庫抽象層的當前版本都包含這樣的功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.