2009-07-05 4 views
12

Tôi sử dụng mã sau để giao dịch trong Zend Framework nhưng hàm rollback không hoạt động (Dữ liệu được chèn vào cơ sở dữ liệu bởi insertSome ($ data)). Có gì sai?Không thể khôi phục giao dịch trong Zend Framework

  $db->beginTransaction(); 
      try{ 
       $model->insertSome($data); 
       $model->insertAll($data2); //this line cannot be run and the whole transaction should be rolled back. 
       $db->commit(); 
      } catch (Exception $e) { 
       $db->rollBack(); 
       echo $e->getMessage(); 
      } 
+7

DB của bạn có phải là cơ hội bằng cách sử dụng bảng MyISAM không? Họ không hỗ trợ giao dịch. Bạn sẽ phải sử dụng các bảng InnoDB nếu bạn muốn hỗ trợ giao dịch. – nos

+0

Có, tôi đang sử dụng các bảng MyISAM. Tôi đã thay đổi thành các bảng InnoDB và nó hoạt động. Cảm ơn. – Billy

Trả lời

20

Chúng ta không thể nhận được câu hỏi này ra khỏi danh sách các câu hỏi "chưa được trả lời" trên StackOverflow trừ khi có ít nhất một câu trả lời với một phiếu bầu tán thành. Vì vậy, tôi lặp lại các giải pháp mà bạn đã thảo luận ở trên trong các ý kiến.

@nos gợi ý:

là DB của bạn bằng cách sử dụng bất kỳ cơ hội MySQL bảng MyISAM? Họ không hỗ trợ giao dịch . Bạn sẽ phải sử dụng các bảng InnoDB nếu bạn muốn giao dịch hỗ trợ.

@Billy đáp ứng:

Vâng, tôi đang sử dụng các bảng MyISAM. Tôi đã thay đổi thành các bảng InnoDB và nó hoạt động. Cảm ơn.

(Tôi đã đánh dấu này như một câu trả lời wiki cộng đồng vì vậy tôi không nhận được bất kỳ điểm từ nó.)

2

Nếu bàn của tôi là InnoDB, (nhìn thấy từ SHOW CREATE TABLE xxx) và giao dịch của tôi đã không quay trở lại, bạn sẽ gợi ý điều gì?

CREATE TABLE `EarningCode` (
`ID` int(11) NOT NULL auto_increment, 
`EarningCode` varchar(16) collate utf8_unicode_ci NOT NULL, 
`Description` varchar(255) collate utf8_unicode_ci NOT NULL, 
`DateEffective` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
`Rate` float NOT NULL, 
PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=1239 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

Đó là một phần của đơn vị xét nghiệm: Tôi có một phương pháp thiết lập bắt đầu một transation:

protected function setUp() 
{ 
    global $db; 

    $db->beginTransaction(); 

    // Insert this tested object into db. 
} 

và một phương pháp xé xuống mà cần đảm bảo rằng hàng không đưa vào db (mỗi thời gian thử nghiệm được chạy trong lớp thử nghiệm này, nó thực thi cặp setUp/tearDown và vì vậy tôi không muốn các bản sao lấp đầy bảng db của tôi).

protected function tearDown() 
{ 
    global $db; 

    $db->rollBack(); 
} 

Tôi đã kiểm tra những gì SQL được thực thi, và tôi có thể nhìn thấy autocommit được thiết lập là false khi giao dịch được bắt đầu, và chuyển sang đúng sau khi lăn trở lại, nhưng hàng vẫn chèn vào.

0

Mã của bạn là ok.

Kiểm tra tùy chọn bảng của bạn. Bạn cần sử dụng công cụ Transacctional với InnoDb

2

Để sử dụng trong tương lai, để biết đó có thực sự là ngoại lệ DB hay không, hãy sử dụng Zend_Db_Exception để thay thế.

} catch (Zend_Db_Exception $e) { 
    $db->rollBack(); 
    echo $e->getMessage(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
}