Mysql事务处理问题_MySQL
今天和同学讨论起数据库事务处理的问题,感觉讨论中明白了一些,有些知识看过了,但是没有实际使用还是不理解。
事务处理就是将一系列操作当做一个原子操作,要么全部执行成功,如果执行失败则保留执行期的状态。通过提交和回滚机制来实现操作,如果全部执行成功通过提交执行commit结果就会记录到数据库中,如果执行失败通过回滚操作rollback将发生错误之前的所有错误消除,回退到原来状态。
事务都应该具备ACID特征。所谓ACID是Atomic(原子性),Consistent(一致性),Isolated(隔离性),Durable(持续性)四个词的首字母所写,下面以“银行转帐”为例来分别说明一下它们的含义:
原子性:组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。换句话说,事务是不可分割的最小单元。比如:银行转帐过程中,必须同时从一个帐户减去转帐金额,并加到另一个帐户中,只改变一个帐户是不合理的。
一致性:在事务处理执行前后,数据库是一致的。也就是说,事务应该正确的转换系统状态。比如:银行转帐过程中,要么转帐金额从一个帐户转入另一个帐户,要么两个帐户都不变,没有其他的情况。
隔离性:一个事务处理对另一个事务处理没有影响。就是说任何事务都不可能看到一个处在不完整状态下的事务。比如说,银行转帐过程中,在转帐事务没有提交之前,另一个转帐事务只能处于等待状态。
持续性:事务处理的效果能够被永久保存下来。反过来说,事务应当能够承受所有的失败,包括服务器、进程、通信以及媒体失败等等。比如:银行转帐过程中,转帐后帐户的状态要能被保存下来。
注意Mysql支持的存储引擎中,默认为MyISAM,是不支持事务处理的,一般都有InnoDB,是支持事务型的。
(1)如果对一个表进行操作的时候需要事务支持,需要配置存储引擎为InnoDB等支持事务型的。
create table XX() engine=InnoDB;
(2)默认情况下,mysql是自动提交模式(autocommit=1),此时会在每一条语句执行完毕后将所做修改立即提交,此时的commit相当于没用的,rollback只对前一句语句起作用,其实也没用,一条mysql语句默认也是原子操作,没必要。
如果设置默认事务处理,需要将自动提交模式关闭即将autocommit设置为0.
set autocommit=0; 设置模式为关闭
select @@autocommit; 查看值是否已经改变
注意,如果在客户端设置的话,设置完,之后断掉连接后再重连又恢复默认设置。每个客户端只能设置客户自己的。
(3)如果自动提交模式是打开的,则需使用语句:
start transaction; 开始事务处理
XX1;
XX2;
commit; / rollback;
来开始事务处理;而如果设置为关闭,则无需使用start transaction,连续语句就为事务指导rollback或者commit。
(4)注意创建、改变、删除数据库或者其中的数据定义语言以及锁有关的都不能成为事务的一部分,如下面:
start transaction;insert into test1 values("8"); create table test2(i int); insert into test1 values("8");rollback;
执行一个事务处理,当执行到要创建表时,mysql会自动提交,然后再执行创建语句。如果test1的i为主键,则第三条语句出错,回滚时test1还是插入成功,且创建了表test2.
(5)python中使用数据库,最好采用这种形式,
import MySQLdbtry: conn = MySQLdb.connect(host="localhost",user="root",passwd="your passwd",db="dbName") except MySQLdb.Error,e: print "Mysql Error %d: %s" % (e.args[0], e.args[1])else: pass #conn.close()
try: cur=conn.cursor() cur.execute('set autocommit=0') #cur.execute('start transaction') cur.execute('insert into test1 values("8")') cur.execute('insert into test1 values("8")') except MySQLdb.Error,e: conn.rollback() print "Mysql Error %d: %s" % (e.args[0], e.args[1])else: conn.commit() cur.close() conn.close()
(6)并行处理问题
Mysql是一个多用户的系统,有多用户在同一时间访问统一数据表,MySIAM采用的是数据表级的锁定标记,来保证同一时间只有一个用户访问此表;Innodb采用了数据行级的访问机制,即两个用户可以对同一个表中不同行的数据同时进行修改,而如果是同一行,则先来的用户先锁住此行,操作结束释放锁后,下一个用户才能操作。
(7)事务处理的隔离性问题
InnoDB默认的隔离级别是repeatable read,如果某个用户两次执行同一个select语句,其结果是可重复的,如果在事务期间有用户对所要读取的数据进行了操作,那么也不会有显示,比如一个存储引擎为innodb的表,如果有一个客户用事务来select读取表数据,另一个用户此时对表做了一个插入之类的操作,第一个用户再进行同样的select读取时,显示数据是没有变化的。
(8)多语句操作非原子操作
如上面(6)中会出现一个问题,如果是一个事务操作,读取数据后,想对数据进行操作,但是可能有另外一个人对此做了操作,那再对此数据进行操作就不对了。
此时需要明确加锁来锁住表,防止别人更改数据,执行结束后释放锁。
lock tables XX write;
XXXXXX;
unlock tables;
也可以使用相对更新代替绝对更新,相对于当前值进行更新,不根据上次的值算出一个绝对值进行更新。这样避免了多条语句的非原子操作。
set a = a - 3 XXXXXXXXXXX;

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

苹果公司最新发布的iOS18、iPadOS18以及macOSSequoia系统为Photos应用增添了一项重要功能,旨在帮助用户轻松恢复因各种原因丢失或损坏的照片和视频。这项新功能在Photos应用的"工具"部分引入了一个名为"已恢复"的相册,当用户设备中存在未纳入其照片库的图片或视频时,该相册将自动显示。"已恢复"相册的出现为因数据库损坏、相机应用未正确保存至照片库或第三方应用管理照片库时照片和视频丢失提供了解决方案。用户只需简单几步

Hibernate多态映射可映射继承类到数据库,提供以下映射类型:joined-subclass:为子类创建单独表,包含父类所有列。table-per-class:为子类创建单独表,仅包含子类特有列。union-subclass:类似joined-subclass,但父类表联合所有子类列。

PHP中处理数据库连接报错,可以使用以下步骤:使用mysqli_connect_errno()获取错误代码。使用mysqli_connect_error()获取错误消息。通过捕获并记录这些错误信息,可以轻松识别并解决数据库连接问题,确保应用程序的顺畅运行。

如何在PHP中使用MySQLi建立数据库连接:包含MySQLi扩展(require_once)创建连接函数(functionconnect_to_db)调用连接函数($conn=connect_to_db())执行查询($result=$conn->query())关闭连接($conn->close())

在Golang中使用数据库回调函数可以实现:在指定数据库操作完成后执行自定义代码。通过单独的函数添加自定义行为,无需编写额外代码。回调函数可用于插入、更新、删除和查询操作。必须使用sql.Exec、sql.QueryRow或sql.Query函数才能使用回调函数。

可以通过使用gjson库或json.Unmarshal函数将JSON数据保存到MySQL数据库中。gjson库提供了方便的方法来解析JSON字段,而json.Unmarshal函数需要一个目标类型指针来解组JSON数据。这两种方法都需要准备SQL语句和执行插入操作来将数据持久化到数据库中。

在C++中使用DataAccessObjects(DAO)库连接和操作数据库,包括建立数据库连接、执行SQL查询、插入新记录和更新现有记录。具体步骤为:1.包含必要的库语句;2.打开数据库文件;3.创建Recordset对象执行SQL查询或操作数据;4.遍历结果或按照具体需求更新记录。

通过Go标准库database/sql包,可以连接到MySQL、PostgreSQL或SQLite等远程数据库:创建包含数据库连接信息的连接字符串。使用sql.Open()函数打开数据库连接。执行SQL查询和插入操作等数据库操作。使用defer关闭数据库连接以释放资源。
