delphi2009,如何检测mysql事务是否被回滚?

qrjkbowd  于 2021-06-25  发布在  Mysql
关注(0)|答案(0)|浏览(191)

调整mysql事务中的代码-在任何异常情况下回滚我通过一个事务将两个插入到一个表中,如果其中一个插入失败,该事务将回滚。我想使用delphi来检测是否发生了回滚。
我已经使用try-except块来检查执行整个事务时的错误,但是大概回滚被delphi视为正确的执行。
要做到这一点,唯一的方法是在事后使用select来查看数据是否存在吗?
这可能很棘手,因为如果同一个人、同一金额、同一天发生两个事务,插入的实时数据可能会重复(每一行的唯一性是通过一个自动递增列(subs\u paid\u id)实现的,该列不会出现在insert中)
冒着冗长的风险,我在下面展示了表的dll和执行插入的delphi代码。
(tosql只是一个类,它将传递的各种参数转换为适合sql字符串的格式。myconnection1是一个连接到远程数据库的devart mydac tmy连接)

/*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;

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题