事务特性
MySQL事务是一组SQL语句,它们被视为单个工作单元,要么全部执行成功,要么全部失败回滚。MySQL使用事务来保证在多个并发用户之间的数据一致性。
MySQL事务遵循ACID原则,即:
原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中的所有操作要么全部完成,要么全部不完成。
一致性(Consistency):当事务完成时,所有数据都必须处于一致的状态,即数据库从一个一致性状态转移到另一个一致性状态。
隔离性(Isolation):每个事务都应该在另一个事务提交之前独立运行,不应该互相干扰。
持久性(Durability):一旦事务提交,它对数据库中的数据更改应该是永久的,即使发生系统故障也应该是如此。
管理事务
显示启动事务
注意:只有事务型存储引擎中的DML语句方能支持此类操作 ,包括SELECT、INSERT、UPDATE、DELETE等。
结束事务
如果事务执行成功,使用以下语句提交:
如果事务执行失败,使用以下语句回滚:
在默认情况下,MySQL自动提交事务,也就是执行一条语句后就会自动提交。如果要手动提交事务,需要使用以下语句关闭自动提交:
事务支持保存点
MySQL还支持保存点(Savepoint)的概念,即在事务中创建一个保存点,可以在后续操作中回滚到这个保存点。保存点使用以下语句创建:
使用以下语句回滚到保存点:
查看事务:
锁等待
事务隔离
事务隔离级别指的是在多个并发事务执行时,保证每个事务所见到的数据视图的隔离程度。MySQL 提供了四个标准隔离级别:
READ UNCOMMITTED(未提交读):在一个事务中,可以读取另一个未提交的事务中的数据。此级别存在最严重的问题,即脏读(Dirty Read)。
READ COMMITTED(提交读):一个事务只能读取另一个事务已经提交的数据。此级别避免了脏读,但仍可能出现不可重复读(Non-repeatable Read)。
REPEATABLE READ(可重复读):在同一事务中,多次读取同一个数据时,其值保持不变。此级别解决了不可重复读问题,但仍可能出现幻读(Phantom Read)。
SERIALIZABLE(可串行化):在这个级别下,所有的事务串行执行。这样可以避免脏读、不可重复读和幻读,但对性能的影响较大。
说明
读未提交(Read Uncommitted)隔离级别:在该级别下,即使一个事务还没有提交,其对数据的修改对于其他事务也是可见的。
示例:假设当前有两个事务 T1 和 T2,T1 执行以下语句:
此时 T1 可能会读到 T2 已经插入的一行记录,即使 T2 还没有提交。
读提交(Read Committed)隔离级别:在该级别下,事务只能看见已经提交的事务所做的修改。
示例:假设当前有两个事务 T1 和 T2,T1 执行以下语句:
此时 T1 只能看到已经提交的事务所做的修改,不能看到 T2 未提交的修改;可读取到提交数据,但未提交数据不可读,产生不可重复读,即可读取到多个提交数据,导致每次读取数据不一致;且T2如果需要更新该条数据,需要等T1提交后才可,否则才是锁等待
可重复读(Repeatable Read)隔离级别:在该级别下,每个事务第一次读取数据时,都会对其做一个快照,事务在本次读取过程中只能看到这个快照中的数据。
示例:假设当前有两个事务 T1 和 T2,T1 执行以下语句:
此时 T2只能看到第一次读取时的数据快照中的数据,即使 T1 在 T2 执行后修改了数据,T2 也无法看到 T1 的修改,直到 T2 结束。
串行化(Serializable)隔离级别:在该级别下,所有事务都按顺序依次执行,不存在并发的情况。
示例:假设当前有两个事务 T1 和 T2,T1 执行以下语句:
此时 T1 只有在 T2 执行完之后才能执行,不存在并发的情况。
READ COMMITTED和REPEATABLE READ两个隔离级别的区别主要在于锁定和可重复读方面。
READ COMMITTED级别下,事务只会锁定查询到的行,查询结束后就会释放锁定,这样可以避免长时间的锁定,但也会导致在同一事务内多次查询同一行数据时,可能会得到不同的结果,因为其他事务可能已经修改了这一行数据。
REPEATABLE READ级别下,事务会锁定查询的所有行,直到事务结束才会释放,这样可以保证在同一事务内多次查询同一行数据时,得到的结果都是一致的。但同时也会导致在同一事务内并发更新同一行数据时,可能会出现死锁的情况。
因此,如果应用程序对数据的一致性要求比较高,可以使用REPEATABLE READ隔离级别,否则可以使用READ COMMITTED隔离级别来提高并发性能。
MVCC和事务的隔离级别:
MVCC(多版本并发控制机制)只在REPEATABLE READ和READ COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁.。
指定事务隔离级别:
服务器变量tx_isolation指定,默认为REPEATABLE-READ,可在GLOBAL和SESSION级进行设置
服务器选项中指定
死锁:
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态
死锁是指两个或多个事务互相持有对方所需资源而无法继续执行的一种情况。比如,事务A持有资源X,请求资源Y,而事务B持有资源Y,请求资源X,这样两个事务之间就形成了一个死锁。如果不解决死锁,这些事务将无法完成,从而导致系统崩溃或失效。
假设有两个事务T1和T2,操作的表为table,同时执行以下操作:
在以上操作中,事务T1和T2都试图更新id为1和2的行,但是它们的更新顺序是相反的,因此在执行过程中会发生死锁。例如,T1首先获取了id=1的行的锁,然后试图获取id=2的行的锁,而T2则首先获取了id=2的行的锁,然后试图获取id=1的行的锁,因此两个事务都等待对方释放锁,进入了死锁状态。
服务器租用托管,机房租用托管,主机租用托管,https://www.e1idc.com