资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

mysql事务怎么检查 mysql事务用法

mysql 事务怎么判断是否回滚

DELIMITER $$

创新互联建站服务项目包括博乐网站建设、博乐网站制作、博乐网页制作以及博乐网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,博乐网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到博乐省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

BEGIN

DECLARE t_error INTEGER DEFAULT 0;

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1 ;

START TRANSACTION;

UPDATE table1 SET a = '111';

INSERT INTO table2 (b) VALUES ('222');

INSERT INTO table3 (c) VALUES ('333');

IF t_error = 1 THEN

ROLLBACK;

ELSE

COMMIT;

END IF;

END$$

DELIMITER ;

mysql 事务内的更新可以在事务内查询出来吗

背景:

1)mysql:Ver 14.12 Distrib 5.0.45, for Win32 (ia32)

2)mysql odbc驱动:3.51.22

3)vs2005

4)客户端用ado,odbc驱动连接mysql数据库

5)表tb_5100定义如下:

CREATE TABLE `tb_5100` (

`account_id` BIGINT(20) NOT NULL,

`service_id` INT(11) NOT NULL,

`f002d_5105` DATE NOT NULL,

`object_id` INT(11) NOT NULL AUTO_INCREMENT,

PRIMARY KEY (`object_id`)

) ENGINE=INNODB DEFAULT CHARSET=gbk;

object_id字段AUTO_INCREMENT(自增长)

f002d_5105字段date类型,不能为空

问题:

开启一个事务

往tb_5100表插入一条记录,f002d_5105为空或者''(违反非空约束);

获取新记录的自增长字段object_id的值

根据自增长字段object_id查询新记录查不出来

提交事务

记录已经插入到数据库中,用mysql客户端工具可以查询出记录。

示例代码如下所示:

pdbor-BeginTrans();

string sql = "INSERT INTO tb_5100(account_id,service_id,f002d_5105) VALUES(10068,300,'')";

if( !pdbor-Execute(adCmdText,sql.c_str()) ){

pdbor-RollbackTrans();

return -1;

}

///获得自增长字段值

unsigned __int64 service_serial;

if( pdbor-GetDBExt()-GetLastID(service_serial,1,"") ){

pdbor-RollbackTrans();

return -2;

}

sql = LogMsg("SELECT * FROM tb_5100 where object_id=%d",service_serial);

CRecordset *prs = pdbor-Query(adCmdText,sql.c_str());

if( prs == NULL ){

pdbor-RollbackTrans();

return -3;

}

if( prs-IsEof() ){

pdbor-RollbackTrans();

return -4;///查询不出来,函数返回-4

}

pdbor-CommitTrans();

return 0;

经多次实验,

将f002d_5105字段改为允许为NULL,记录可以成功插入,在事务内,可以查询出新记录。

将数据库模式设置为STRICT_TRANS_TABLES严格模式(修改my.ini,在[mysqld]段,设置sql-mode="STRICT_TRANS_TABLES"),insert失败。

分析:

导致问题的原因为日期型字段f002d_5105数据非法的问题。新记录插入后,f002d_5105字段的值为'0000-00-00',为非法的日期型数据。MySQL是允许无效数据的存在的。详见(mysql中对无效数据的约束)。

而由于非法数据,导致同一个事务内能插入成功,但查询不来的问题,确实不解,这可能跟驱动有关,但只是个猜测。

解决此问题的办法应该是避免出现无效数据,应该使用严格的约束模式,即STRICT_TRANS_TABLES。参见。

参考:

在MySQL5.0.2之前,MySQL对非法或不当值并不严厉,而且为了数据输入还会强制将它们变为合法值。在MySQL5.0.2和更高版本中,保留了以前的默认行为,但你可以为不良值选择更传统的处理方法,从而使得服务器能够拒绝并放弃出现不良值的语句。本节介绍了MySQL的默认行为(宽大行为),新的严格的SQL模式,以及它们的区别。如果你未使用严格模式,下述情况是真实的。如果将“不正确”的值插入到列,如将NULL值插入非NULL列,或将过大的数值插入数值列,MySQL会将这些列设置为“最可能的值”,而不是生成错误信息。如果试图将超范围的值保存到数值列,MySQL服务器将保存0(最小的可能值)取而代之,或最大的可能值。对于字符串,MySQL或保存空字符串,或将字符串尽可能多的部分保存到列中。如果打算将不是以数值开头的字符串保存到数值列,MySQL将保存0。MySQL允许将特定的不正确日期值保存到DATE和DATETIME列(如“2000-02-31”或“2000-02-00”)。其观点在于,验证日期不是SQL服务器的任务。如果MySQL能保存日期值并准确检索相同的值,MySQL就能按给定的值保存它。如果日期完全不正确(超出服务器能保存的范围)将在列中保存特殊的日期值“0000-00-00”取而代之。如果试图将NULL值保存到不接受NULL值的列,对于单行INSERT语句,将出现错误。对于多行INSERT语句或INSERTINTO...SELECT语句,MySQL服务器会保存针对列数据类型的隐含默认值。一般情况下,对于数值类型,它是0,对于字符串类型,它是空字符串(‘‘),对于日期和时间类型是“zero”。如果INSERT语句未为列指定值,如果列定义包含明确的DEFAULT子句,MySQL将插入默认值。如果在定义中没有这类DEFAULT子句,MySQL会插入列数据类型的隐含默认值。采用前述规则的原因在于,在语句开始执行前,无法检查这些状况。如果在更新了数行后遇到这类问题,我们不能仅靠回滚解决,这是因为存储引擎可能不支持回滚。中止语句并不是良好的选择,在该情况下,更新完成了“一半”,这或许是最差的情况。对于本例,较好的方法是“仅可能做到最好”,然后就像什么都未发生那样继续。在MySQL5.0.2和更高版本中,可以使用STRICT_TRANS_TABLES或STRICT_ALL_TABLESSQL模式,选择更严格的处理方式。STRICT_TRANS_TABLES的工作方式:对于事务性存储引擎,在语句中任何地方出现的不良数据值均会导致放弃语句并执行回滚。对于非事务性存储引擎,如果错误出现在要插入或更新的第1行,将放弃语句。(在这种情况下,可以认为语句未改变表,就像事务表一样)。首行后出现的错误不会导致放弃语句。取而代之的是,将调整不良数据值,并给出告警,而不是错误。换句话讲,使用STRICT_TRANS_TABLES后,错误值会导致MySQL执行回滚操作,如果可以,所有更新到此为止。要想执行更严格的检查,请启用STRICT_ALL_TABLES。除了非事务性存储引擎,它与STRICT_TRANS_TABLES等同,即使当不良数据出现在首行后的其他行,所产生的错误也会导致放弃语句。这意味着,如果错误出现在非事务性表多行插入或更新过程的中途,仅更新部分结果。前面的行将完成插入或更新,但错误出现点后面的行则不然。对于非事务性表,为了避免这种情况的发生,可使用单行语句,或者在能接受转换警告而不是错误的情况下使用STRICT_TRANS_TABLES。要想在第1场合防止问题的出现,不要使用MySQL来检查列的内容。最安全的方式(通常也较快)是,让应用程序负责,仅将有效值传递给数据库。有了严格的模式选项后,可使用INSERTIGNORE或UPDATEIGNORE而不是不带IGNORE的INSERT或UPDATE,将错误当作告警对待。

如何查询mysql事务未提交

如何查询mysql事务未提交

打开全日志后可以看。

打开的方法是:

1、5.0的版本

在配置文件的mysqld段中,增加

log=/var/log/mysql.log(或者其他的你想放日志的路径)

然后重启数据库

2、如果是5.1的版本

在配置文件的mysqld段中,增加

general_log_file=/var/log/mysql.log

然后重启数据库

5.1版本也可以不用重启,全局设置一下,方法是:

set global general_log=1;

set global general_log_file=/var/log/mysql.log;

打开日志后,查看未提交事务的方法为:

连接到数据库后,会分配一个连接id,然后追踪此连接id,找到此连接执行的所有sql,如果有begin,而没有commit,那么这个语句就是未提交的。

mysql 查当前有哪些分布式事务

1.普通事务

以 begin / start transaction 开始,commit / rollback 结束的事务。或者是带有保存点 savepoint 的事务。

2. 链式事务

一个事务在提交的时候自动将上下文传给下一个事务,也就是说一个事务的提交和下一个事务的开始是原子性的,下一个事务可以看到上一个事务的处理结果。MySQL 的链式事务靠参数 completion_type 控制,并且回滚和提交的语句后面加上 work 关键词。

3. 嵌套事务

有多个 begin / commit / rollback 这样的事务块的事务,并且有父子关系。子事务的提交完成后不会真的提交,而是等到父事务提交才真正的提交。

4. 自治事务

内部事务的提交不随外部事务的影响,一般用作记录内部事务的异常情况。MySQL 不支持自治事务,但是某些场景可以用 MySQL 的插件式引擎来变相实现。


当前文章:mysql事务怎么检查 mysql事务用法
转载源于:http://cdkjz.cn/article/doggepd.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220