Delphi 2009,如何检测MySQL事务是否已回滚?

时间:2018-04-18 14:35:22

标签: mysql transactions rollback delphi-2009

调整来自mysql transaction - roll back on any exception的代码我通过事务进行两次插入,如果插入失败则回滚。我想使用Delphi来检测是否发生了回滚。

我已经使用try - except块来检查执行整个事务时的错误,但可能是Delphi将回滚视为正确的执行。

这是唯一的方法,以后使用SELECT来查看数据是否存在?

这可能很棘手,因为如果同一个人,相同金额和同一天发生了两次交易,插入的实时数据可能会重复。 (每行的唯一性通过自动增量列(subs_paid_id)实现,并且不会出现在插入中)

冒着冗长的风险,我在下面显示了表的DLL和用于插入的delphi代码。

ToSQL 只是一个将各种传递参数转换为适合SQL字符串格式的类.MyConnection1是一个与远程数据库连接的Devart MyDAC TMyConnection) < / p>

/*DDL Information*/
-------------------

CREATE TABLE subscriptions_paid 
(
  subscription_year varchar(4) NOT NULL DEFAULT '',
  member_id int(11) NOT NULL DEFAULT '0',
  individual_subs_due float DEFAULT NULL,
  individual_subs_paid float DEFAULT NULL,
  payment_date date DEFAULT NULL,
  import_date date DEFAULT NULL,
  user_comment varchar(100),
  subs_paid_id int(11) NOT NULL AUTO_INCREMENT,

  PRIMARY KEY (subscription_year,member_id,subs_paid_id),
  KEY subs_paid_id (subs_paid_id)
) 
ENGINE=InnoDB AUTO_INCREMENT=538 DEFAULT CHARSET=utf8

和Delphi代码,包括生成SQL是

procedure TFrm_EditSubsPaid.btnConfirmTransferToSelectedClick(Sender: TObject);

//make sql to add a new payment for FirstMemberID, FirstSubsDue, FirstSubsYear using
//dtpNewPaymentDate, edtNewPaymentComment,  edtNewPayment and
//a new negative 'payment' for   SecondMemberID,  SecondSubsDue, 
//SecondSubsYear, using  edtAmountToTransferFrom , dtpTransferFrom and  
//edtNewTransferFromComment

var overpaid : single;
begin
if TransferAmountValid then
   begin
   SQL := ''
   +'DELIMITER $$  '
   +'CREATE PROCEDURE transfer()  '
   +'BEGIN '
   //next two lines allow for all the transaction to be rolled back if any insert fails
   +'   DECLARE `_rollback` BOOL DEFAULT 0; '
   +'   DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1;  '

   + 'START TRANSACTION '
   +'INSERT INTO subscriptions_paid '   //the positive payment into account
   +'       (                            '
   +'              subscription_year   , '
   +'              member_id           , '
   +'              individual_subs_due , '
   +'              individual_subs_paid, '
   +'              payment_date        , '
   +'              import_date         , '
   +'              user_comment          '
   +'       ) '
   +'       VALUES '
   +'       (                                 '
   +'         ToSQL.Text(FirstSubsYear) + ', '
   +          FirstMemberID + ', '
   +          ToSQL.Float(StrToFloat(FirstSubsDue)) +', '
   +          ToSQL.Float(StrToFloat(edtAmountToTransferFrom.Text)) +', '
   +          ToSQL.Date(DateOf(dtpTransferFrom.date)) + ', '
   +          'NULL' + ', '
   +          ToSQL.Text('(Tfr From ' + SecondMemberID +') ' + edtNewTransferFromComment.text) +' '
   +          ');'

   +'INSERT INTO subscriptions_paid '     //the negative payment out of account
   +'       (                            '
   +'              subscription_year   , '
   +'              member_id           , '
   +'              individual_subs_due , '
   +'              individual_subs_paid, '
   +'              payment_date        , '
   +'              import_date         , '
   +'              user_comment          '
   +'       ) '
   +'       VALUES '
   +'       ( '
   +        ToSQL.Text(FirstSubsYear) + ', '
   +        SecondMemberID + ', '
   +        ToSQL.Float(StrToFloat(SecondSubsDue)) +', '
   +        ToSQL.Float(StrToFloat('-' + edtAmountToTransferFrom.Text)) +', '
   +        ToSQL.Date(DateOf(dtpTransferFrom.date)) + ', '
   +        'NULL' + ', '
   +        ToSQL.Text('(Tfr To ' + FirstMemberID +') ' + edtNewTransferFromComment.text) +' '
   +        ');'

   //next five lines allow for all the transaction to be rolled back if any insert fails
   +'IF `_rollback` THEN '
   +'        ROLLBACK;   '
   +'ELSE                '
   +'        COMMIT;     '
   +'END IF; ' 

   +'END$$'
   +'DELIMITER ;'   ;


  try
   begin
     dMod.MyConnection1.ExecSQL(sql);
     dMod.MyConnection1.ExecSQL('CALL transfer;');


   // ???? now check if the inserts went OK ???

     end;
 except
 on E : Exception do
     begin
       showmessage (
                        'Exception class name = '+E.ClassName+ slinebreak
                +  'Exception message = '+E.Message);
      end  //on E
 end;//try
 end; //if


end;

0 个答案:

没有答案