Sunday, May 2, 2010

Codeigniter Oracle Transaction BUG

Guys, ini baru ketemuin BUG. Khusus nya
utk Driver Database Oracle, OCI8.
Seharus nya transaksi yg di awali
dg trans_start(TRUE) tidak akan ter-COMMIT.
$this->db->trans_start(TRUE);
$this->db->simple_query("insert into test
(id,name)
values
('1','ade1') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade2') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade3') ");
$this->db->trans_complete();

Expected result:
rollback

Actual result:
rollback

Semua berjalan lancar, transaksi di rollback.
Lohh mana BUG nya? Nahh cuba sisipkan
'SELECT' query di antara nya :D.
Sudah terlihat BUG nya? Query 'INSERT'
sebelum 'SELECT' ter-COMMIT. Di mana seharus nya
tidak boleh!!! Ceritanya begini, misalkan
kita ada transaksi seperti ini:
$this->db->trans_start(TRUE);
$this->db->simple_query("insert into test
(id,name)
values
('1','ade1') ");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade2') ");
$result = $this->db->query("select * from test");
$this->db->simple_query("insert into test
(id,name)
values
('1','ade3') ");
$this->db->trans_complete();

Expected result:
rollback

Actual result:
2 rows inserted

Nah setelah saya telusurin driver nya.
Ternyata BUG nya ada di
/system/database/driver/oci8/oci8_result.php
line : 46 dan 50. Fungsi ociexecute bila hanya terima
1 parameter maka parameter ke 2 nya di set
menjadi OCI_COMMIT_ON_SUCCESS. Kebayangkan?
Jadi seluruh transaksi insert akan ter-COMMIT
walaupun trans_complete belum terpanggil.

Solusi nya cukup rubah line 46 dan 50,
@ociexecute($this->stmt_id);
menjadi
@ociexecute($this->stmt_id, OCI_DEFAULT);

Di execute lagi query di atas yg ada 'SELECT'
query di antaranya dan expected result nya
tercapai.

Coding for life, coding with ethic.

No comments: